You are on page 1of 808

DE LA UNIVERSIDAD DE BUENOS AIRES

FACULTAD DE INGENIERA

Tesis de Grado en Ingeniera Informtica

Diseo de un Sistema de Intercambio de Informacin para Dispositivos Intercomunicados por Redes PLC de Automviles

Tesista: Sr. Fernando Ariel Beunza Director: Ing. Jorge Alberto

SEPTIEMBRE 2011

Tesis de Grado en Ingeniera Informtica

Facultad de Ingeniera Universidad de Buenos Aires

Diseo de un Sistema de Intercambio de Informacin para Dispositivos Intercomunicados por Redes PLC de Automviles

Sr. Fernando Ariel Beunza Tesista

Ing. Jorge Alberto Director

SEPTIEMBRE 2011

Tesis de Grado en Ingeniera Informtica

Resumen
Desde hace aos para mejorar las prestaciones de dispositivos que cada vez presentan ms cantidad de componentes electrnicos las interconexiones dedicadas estn siendo reemplazadas por buses de datos. Un mbito en donde esto sucede es en la industria automotriz, en donde los vehculos actuales trabajan con redes como CAN [Bosch91], J1850 [SAE94], entre otras; en donde los dispositivos electrnicos comparten informacin por medio de un nico cableado para datos. En los ltimos aos ha surgido la idea de combinar en un nico cableado la energa de alimentacin y la informacin, lo que se conoce como PLC. Los avances, respecto a la tecnologa PLC, se encuentran destinados ms que nada a infraestructura edilicia, existiendo una variedad de estndares de los cuales muchos no implementan todas las capas del modelo OSI [ISO7498-1]. Respecto a los avances de sta tecnologa en el ambiente automotriz, se han desarrollado trabajos que slo tratan las capas fsica y enlace del modelo OSI. La idea del presente trabajo es tomar como punto de partida los antecedentes mencionados y construir un sistema que permita compartir informacin encapsulando toda la complejidad involucrada en el proceso de comunicacin y brindando una interfaz que sea simple de utilizar para los dispositivos clientes del sistema.

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

ndice
1. Introduccin....................................................................................................................................15 2. Antecedentes...................................................................................................................................17 2.1. Tecnologa PLC.......................................................................................................................17 2.1.1. X10...................................................................................................................................18 2.1.1.1. Mtodo de transmisin..............................................................................................18 2.1.1.2. Estructura de mensaje................................................................................................19 2.1.1.3. Esquema de direccionamiento...................................................................................19 2.1.2.4. Funciones...................................................................................................................20 2.1.2. CEBus...............................................................................................................................21 2.1.2.1. Mtodo de transmisin..............................................................................................21 2.1.2.2. Estructura de paquete.................................................................................................22 2.1.2.3. Esquema de direccionamiento...................................................................................22 2.1.2.4. Lenguaje de aplicacin..............................................................................................23 2.1.3. CENELEC 50065.............................................................................................................25 2.1.4. UPB..................................................................................................................................26 2.1.4.1. Mtodo de transmisin..............................................................................................27 2.1.4.2. Estructura de paquete.................................................................................................28 2.1.4.3. Esquema de direccionamiento...................................................................................29 2.1.4.4. Comandos..................................................................................................................30 2.1.5. LonWorks.........................................................................................................................31 2.1.5.1. Protocolo CNP...........................................................................................................31 2.1.5.2. Capa fsica.................................................................................................................32 2.1.5.3. Capa de enlace...........................................................................................................33 2.1.5.4. Capa de red................................................................................................................34 2.1.5.5. Capa de transporte.....................................................................................................35 2.1.5.6. Capa de sesin...........................................................................................................36 2.1.5.7. Capa de presentacin.................................................................................................37 2.1.5.8. Capa de aplicacin.....................................................................................................38 2.1.6. HomePlug.........................................................................................................................39 2.1.6.1. HomePlug 1.0............................................................................................................39 2.1.6.2. HomePlug AV...........................................................................................................42 2.1.6.3. HomePlug Green PHY..............................................................................................44 2.2. Redes en automviles..............................................................................................................46 2.2.1. CAN..................................................................................................................................46 2.2.1.1. Modelo de capas........................................................................................................46 2.2.1.2. Capa fsica.................................................................................................................47 2.2.1.3. Capa de enlace...........................................................................................................49 2.2.2. J1850.................................................................................................................................52 2.2.2.1. Modelo de capas........................................................................................................52 2.2.2.2. Capa fsica.................................................................................................................54 2.2.2.3. Capa de enlace...........................................................................................................55 2.2.2.4. Capa de aplicacin.....................................................................................................56 2.2.3. OSEK/VDX......................................................................................................................57 2.2.3.1. Arquitectura...............................................................................................................57 2.2.3.2. Implementacin.........................................................................................................58 2.2.4. LIN....................................................................................................................................58 FernandoArielBeunza79156 7

Tesis de Grado en Ingeniera Informtica 2.2.4.1. Capa fsica.................................................................................................................59 2.2.4.2. Capa de enlace...........................................................................................................60 2.2.5. D2B...................................................................................................................................61 2.2.5.1. Medio fsico...............................................................................................................62 2.2.5.2. Control de acceso al medio........................................................................................63 2.2.5.3. Estructura de paquete.................................................................................................63 2.2.6. MOST...............................................................................................................................64 2.2.6.1. Modelo de dispositivo...............................................................................................64 2.2.6.2. Capa fsica.................................................................................................................64 2.2.6.3. Capa de red................................................................................................................65 2.2.6.4. Capa de aplicacin.....................................................................................................67 2.2.7. FlexRay.............................................................................................................................68 2.2.7.1. Capa fsica.................................................................................................................68 2.2.7.2. Capa lgica................................................................................................................71 2.3. Redes PLC en automviles......................................................................................................73 2.3.1. DC-BUS............................................................................................................................73 2.3.1.1. mbitos de aplicacin...............................................................................................73 2.3.1.2. Medio de comunicacin.............................................................................................74 2.3.1.3. Implementacin.........................................................................................................75 2.3.2. Trabajos sobre PLC en la industria automotriz................................................................75 2.3.2.1. Canal de comunicaciones..........................................................................................76 2.3.2.2. Mtodo de acoplamiento...........................................................................................79 2.3.2.3. Tcnica de modulacin..............................................................................................80 2.3.2.4. Tcnicas modificadas................................................................................................83 3. Descripcin del problema...............................................................................................................85 3.1. Alcance de las soluciones existentes.......................................................................................85 3.1.1. Comunicaciones PLC.......................................................................................................85 3.1.2. Redes de automviles.......................................................................................................86 3.1.3. PLC en automviles..........................................................................................................87 3.2. Requerimientos para la propuesta del presente trabajo...........................................................88 4. Solucin propuesta.........................................................................................................................91 4.1. Capa fsica...............................................................................................................................91 4.1.1. Mtodo de acoplamiento..................................................................................................91 4.1.2. Tcnica de modulacin.....................................................................................................93 4.1.3. Modem PLC.....................................................................................................................94 4.1.4. Implementacin del sistema de comunicaciones..............................................................95 4.1.4.1. Implementacin fsica................................................................................................95 4.1.4.2. Implementacin lgica...............................................................................................97 4.1.5. Estructura de tramas.......................................................................................................102 4.1.6. Funciones adicionales.....................................................................................................102 4.1.7. Primitivas de manejo de la capa fsica............................................................................103 4.2. Capa de enlace.......................................................................................................................105 4.2.1. Subcapa de control de acceso al medio..........................................................................106 4.2.1.1. Caractersticas del medio.........................................................................................106 4.2.1.2. Mtodo de acceso al medio.....................................................................................106 4.2.1.3. Fragmentacin.........................................................................................................109 4.2.1.4. Esquema de direccionamiento.................................................................................111 4.2.1.5. Estructura de tramas................................................................................................111 4.2.1.6. Control de errores....................................................................................................112 8 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica 4.2.1.7. Filtrado de tramas....................................................................................................113 4.2.1.8. Primitivas de manejo de la subcapa de control de acceso al medio........................114 4.2.2. Subcapa de control de lgica de enlace..........................................................................115 4.2.2.1. Multiplexado de protocolos.....................................................................................115 4.2.2.2. Control de flujo de datos.........................................................................................116 4.2.2.3. Estructura de paquetes.............................................................................................117 4.2.2.4. Control de errores....................................................................................................117 4.2.2.5. Primitivas de manejo de la subcapa de control de lgica de enlace........................117 4.2.3. Protocolo de resolucin de direcciones..........................................................................119 4.2.3.1. Principio de funcionamiento....................................................................................119 4.2.3.2. Estructura de mensajes............................................................................................120 4.2.3.3. Primitivas de manejo del protocolo de resolucin de direcciones...........................120 4.2.4. Primitivas de manejo de la capa de enlace.....................................................................121 4.3. Capa de red............................................................................................................................123 4.3.1. Modelo de comunicaciones............................................................................................123 4.3.2. Esquema de direccionamiento........................................................................................124 4.3.3. Estructura de mensajes...................................................................................................125 4.3.4. Primitivas de manejo de la capa de red..........................................................................126 4.4. Capa de transporte.................................................................................................................128 4.4.1. Comunicacin por grupos de difusin............................................................................128 4.4.2. Esquema de identificacin..............................................................................................130 4.4.3. Mensajes.........................................................................................................................130 4.4.4. Primitivas de manejo de la capa de transporte................................................................131 4.5. Capa de sesin.......................................................................................................................132 4.5.1. Establecimiento de sesiones...........................................................................................133 4.5.2. Control del dilogo.........................................................................................................134 4.5.3. Grupos de difusin..........................................................................................................134 4.5.4. Estructura de los mensajes..............................................................................................136 4.5.5. Primitivas de manejo de la capa de sesin.....................................................................136 4.6. Capa de presentacin.............................................................................................................138 4.6.1. Implementacin de datos estructurados..........................................................................138 4.6.2. Esquema multiplataforma...............................................................................................140 4.6.3. Estructura de los mensajes..............................................................................................141 4.6.4. Primitivas de manejo de la capa de presentacin...........................................................141 4.7. Capa de aplicacin.................................................................................................................143 4.7.1. Servicio de mensajera....................................................................................................144 4.7.2. Esquema multiplataforma...............................................................................................145 4.7.3. Primitivas de manejo de la capa de aplicacin...............................................................145 4.7.4. Interfaz C++....................................................................................................................148 4.7.5. Biblioteca de bloques Simulink......................................................................................150 5. Evaluacin de la solucin propuesta............................................................................................151 5.1. Comparacin con redes PLC para automviles.....................................................................151 5.1.1. Evaluacin del mdulo analgico...................................................................................151 5.1.2. Evaluacin del mdulo de procesamiento de seales.....................................................164 5.1.3. Evaluacin del canal de comunicacin...........................................................................168 5.1.4. Comparacin con DC-BUS............................................................................................178 5.1.5. Comparacin con los trabajos sobre PLC en la industria automotriz.............................179 5.2. Comparacin con redes existentes para automviles............................................................180 5.2.1. Comparacin con CAN..................................................................................................180 FernandoArielBeunza79156 9

Tesis de Grado en Ingeniera Informtica 5.2.2. Comparacin con J1850.................................................................................................181 5.2.3. Comparacin con OSEK/VDX.......................................................................................182 5.2.4. Comparacin con LIN....................................................................................................182 5.2.5. Comparacin con D2B...................................................................................................183 5.2.6. Comparacin con MOST................................................................................................184 5.2.7. Comparacin con FlexRay.............................................................................................184 5.3. Caractersticas particulares de la solucin propuesta............................................................185 5.4. Desempeo de la solucin propuesta.....................................................................................186 6. Conclusiones.................................................................................................................................189 6.1. Anlisis de resultados............................................................................................................189 6.2. Trabajos futuros.....................................................................................................................191 7. Referencias...................................................................................................................................193 Apndice A: Implementacin del hardware del modem PLC..........................................................199 A.1. Organizacin del hardware...................................................................................................199 A.2. Implementacin del mdulo analgico.................................................................................201 A.3. Implementacin del mdulo de procesamiento de seales...................................................207 A.4. Implementacin del mdulo de procesamiento....................................................................214 A.5. Implementacin del mdulo de adaptacin RS232..............................................................219 Apndice B: Simulacin del hardware del modem PLC..................................................................221 B.1. Organizacin del hardware...................................................................................................221 B.2. Implementacin del mdulo analgico.................................................................................221 B.3. Implementacin del mdulo de procesamiento de seales...................................................228 Apndice C: Cdigo fuente..............................................................................................................239 C.1. Organizacin del cdigo fuente............................................................................................239 C.2. Especificacin del cdigo fuente de las bibliotecas de uso del modem PLC (plataforma AT89X5X)....................................................................................................................................241 C.2.1. Archivo config.h............................................................................................................242 C.2.2. Archivo modplcap.h.......................................................................................................243 C.2.3. Archivo modplcap__init.c..............................................................................................247 C.2.4. Archivo modplcap_release.c..........................................................................................248 C.2.5. Archivo modplcap_publish.c.........................................................................................248 C.2.6. Archivo modplcap_subscribe.c......................................................................................249 C.2.7. Archivo modplcap_leave.c............................................................................................250 C.2.8. Archivo modplcap_newmsg.c........................................................................................250 C.2.9. Archivo modplcap_copymsg.c.......................................................................................251 C.2.10. Archivo modplcap_putfield.c......................................................................................252 C.2.11. Archivo modplcap_sendmsg.c.....................................................................................252 C.2.12. Archivo modplcap_receivemsg.c.................................................................................253 C.2.13. Archivo modplcap_getfield.c.......................................................................................254 C.2.14. Archivo modplcap_getgrpid.c......................................................................................255 C.2.15. Archivo modplcap_getmsgid.c....................................................................................255 C.2.16. Archivo modplcap_destroymsg.c.................................................................................256 C.2.17. Archivo modplcap_setbuffer.c.....................................................................................257 C.2.18. Archivo modplcap_notify.c.........................................................................................257 C.2.19. Archivo modplcap_poll.c.............................................................................................259 C.2.20. Archivo modplcap_status.c..........................................................................................260 C.2.21. Archivo modplcpp.h....................................................................................................260 C.2.22. Archivo modplcpp__init.c...........................................................................................265 C.2.23. Archivo modplcpp_release.c........................................................................................265 10 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica C.2.24. Archivo modplcpp_publish.c.......................................................................................266 C.2.25. Archivo modplcpp_subscribe.c....................................................................................267 C.2.26. Archivo modplcpp_leave.c..........................................................................................267 C.2.27. Archivo modplcpp_newmsg.c.....................................................................................268 C.2.28. Archivo modplcpp_copymsg.c....................................................................................269 C.2.29. Archivo modplcpp_putfield.c......................................................................................270 C.2.30. Archivo modplcpp_sendmsg.c.....................................................................................272 C.2.31. Archivo modplcpp_receivemsg.c.................................................................................272 C.2.32. Archivo modplcpp_getfield.c......................................................................................273 C.2.33. Archivo modplcpp_getgrpid.c.....................................................................................275 C.2.34. Archivo modplcpp_destroymsg.c................................................................................276 C.2.35. Archivo modplcpp_setbuffer.c....................................................................................276 C.2.36. Archivo modplcpp_notify.c.........................................................................................277 C.2.37. Archivo modplcpp_poll.c............................................................................................279 C.2.38. Archivo modplcpp_status.c..........................................................................................279 C.2.39. Archivo modplcsp.h.....................................................................................................280 C.2.40. Archivo modplcsp__init.c............................................................................................283 C.2.41. Archivo modplcsp_release.c........................................................................................285 C.2.42. Archivo modplcsp_publish.c.......................................................................................286 C.2.43. Archivo modplcsp_subscribe.c....................................................................................287 C.2.44. Archivo modplcsp_leave.c...........................................................................................287 C.2.45. Archivo modplcsp_send.c............................................................................................288 C.2.46. Archivo modplcsp_receive.c........................................................................................290 C.2.47. Archivo modplcsp_setbuffer.c.....................................................................................291 C.2.48. Archivo modplcsp_notify.c..........................................................................................292 C.2.49. Archivo modplcsp_poll.c.............................................................................................293 C.2.50. Archivo modplcsp_status.c..........................................................................................294 C.2.51. Archivo modplcsp_getpayloadsize.c...........................................................................295 C.2.52. Archivo __modplcsp_getbyte__.c...............................................................................295 C.2.53. Archivo __modplcsp_getresult__.c.............................................................................296 C.2.54. Archivo __modplcsp_putbyte__.c...............................................................................297 C.2.55. Archivo __modplcsp_putcmd__.c...............................................................................298 C.2.56. Archivo __modplcsp_puthex__.c................................................................................299 C.2.57. Archivo __modplcsp_putint__.c..................................................................................299 C.2.58. Archivo __modplcsp_sendcmd0__.c...........................................................................300 C.2.59. Archivo __modplcsp_sendcmd1__.c...........................................................................301 C.2.60. Archivo __modplcsp_waitchar__.c.............................................................................302 C.2.61. Archivo serial.h............................................................................................................302 C.2.62. Archivo serial.c............................................................................................................303 C.3. Especificacin del cdigo fuente de las bibliotecas de uso del modem PLC (plataforma Windows).....................................................................................................................................304 C.3.1. Interfaz capa de aplicacin modplcap.dll.......................................................................305 C.3.1.1. Archivo config.h.....................................................................................................305 C.3.1.2. Archivo modplcsp.h................................................................................................306 C.3.1.3. Archivo modplcsp.c................................................................................................307 C.3.1.4. Archivo modplcpp.h...............................................................................................316 C.3.1.5. Archivo modplcpp.c................................................................................................319 C.3.1.6. Archivo modplcap.h................................................................................................327 C.3.1.7. Archivo modplcap.c................................................................................................331 FernandoArielBeunza79156 11

Tesis de Grado en Ingeniera Informtica C.3.2. Interfaz capa de enlace modplcdl.dll..............................................................................337 C.3.2.1. Archivo config.h.....................................................................................................337 C.3.2.2. Archivo modplcdl.h................................................................................................337 C.3.2.3. Archivo modplcdl.c.................................................................................................341 C.3.3. Interfaz capa fsica modplcphy.dll.................................................................................354 C.3.3.1. Archivo config.h.....................................................................................................354 C.3.3.2. Archivo modplcphy.h..............................................................................................355 C.3.3.3. Archivo modplcphy.c..............................................................................................358 C.3.4. Driver del Modem PLC modem_driver.exe..................................................................369 C.3.4.1. Archivo config.h.....................................................................................................370 C.3.4.2. Archivo serial.h.......................................................................................................372 C.3.4.3. Archivo serial.c.......................................................................................................373 C.3.4.4. Archivo modplc.h...................................................................................................378 C.3.4.5. Archivo modplc.c....................................................................................................381 C.3.4.6. Archivo modsp.h.....................................................................................................399 C.3.4.7. Archivo modsp.c.....................................................................................................401 C.3.4.8. Archivo moddl.h.....................................................................................................407 C.3.4.9. Archivo moddl.c.....................................................................................................410 C.3.4.10. Archivo modphy.h................................................................................................418 C.3.4.11. Archivo modphy.c.................................................................................................420 C.3.4.12. Archivo modrv.h...................................................................................................427 C.3.4.13. Archivo moddrv.c.................................................................................................428 C.3.4.14. Archivo modem_driver.c......................................................................................443 C.4. Especificacin del cdigo fuente de las bibliotecas de uso del modem PLC (plataforma Linux)...........................................................................................................................................444 C.4.1. Interfaz capa de aplicacin modplcap.so.......................................................................444 C.4.1.1. Archivo config.h.....................................................................................................445 C.4.1.2. Archivo modplcsp.h................................................................................................445 C.4.1.3. Archivo modplcsp.c................................................................................................447 C.4.1.4. Archivo modplcpp.h...............................................................................................456 C.4.1.5. Archivo modplcpp.c................................................................................................459 C.4.1.6. Archivo modplcap.h................................................................................................467 C.4.1.7. Archivo modplcap.c................................................................................................470 C.4.2. Interfaz capa de enlace modplcdl.so..............................................................................475 C.4.2.1. Archivo config.h.....................................................................................................476 C.4.2.2. Archivo modplcdl.h................................................................................................476 C.4.2.3. Archivo modplcdl.c.................................................................................................478 C.4.3. Interfaz capa fsica modplcphy.so..................................................................................492 C.4.3.1. Archivo config.h.....................................................................................................492 C.4.3.2. Archivo modplcphy.h..............................................................................................492 C.4.3.3. Archivo modplcphy.c..............................................................................................494 C.4.4. Driver del Modem PLC modem_driver.........................................................................506 C.4.4.1. Archivo config.h.....................................................................................................507 C.4.4.2. Archivo serial.h.......................................................................................................509 C.4.4.3. Archivo serial.c.......................................................................................................510 C.4.4.4. Archivo modplc.h...................................................................................................512 C.4.4.5. Archivo modplc.c....................................................................................................516 C.4.4.6. Archivo modsp.h.....................................................................................................534 C.4.4.7. Archivo modsp.c.....................................................................................................536 12 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica C.4.4.8. Archivo moddl.h.....................................................................................................542 C.4.4.9. Archivo moddl.c.....................................................................................................544 C.4.4.10. Archivo modphy.h................................................................................................553 C.4.4.11. Archivo modphy.c.................................................................................................555 C.4.4.12. Archivo modrv.h...................................................................................................562 C.4.4.13. Archivo moddrv.c.................................................................................................563 C.4.4.14. Archivo modem_driver.c......................................................................................580 C.5. Especificacin del cdigo fuente del firmware del modem PLC..........................................582 C.5.1. Archivo config.h............................................................................................................583 C.5.2. Archivo common.h........................................................................................................587 C.5.3. Archivo common.c.........................................................................................................587 C.5.4. Archivo serial.h..............................................................................................................588 C.5.5. Archivo serial.c..............................................................................................................588 C.5.6. Archivo phy.h.................................................................................................................588 C.5.7. Archivo phy.c.................................................................................................................590 C.5.8. Archivo mac.h................................................................................................................599 C.5.9. Archivo mac.c................................................................................................................601 C.5.10. Archivo llc.h................................................................................................................611 C.5.11. Archivo llc.c.................................................................................................................612 C.5.12. Archivo arp.h...............................................................................................................616 C.5.13. Archivo arp.c................................................................................................................617 C.5.14. Archivo dl.h.................................................................................................................621 C.5.15. Archivo dl.c..................................................................................................................623 C.5.16. Archivo net.h................................................................................................................625 C.5.17. Archivo net.c................................................................................................................626 C.5.18. Archivo tp.h.................................................................................................................633 C.5.19. Archivo tp.c..................................................................................................................635 C.5.20. Archivo sp.h.................................................................................................................640 C.5.21. Archivo sp.c.................................................................................................................642 C.5.22. Archivo modem.c.........................................................................................................645 C.6. Especificacin del cdigo fuente del firmware procesador de seales.................................655 C.6.1. Archivo config.h............................................................................................................655 C.6.2. Archivo phy.h.................................................................................................................656 C.6.3. Archivo phy.c.................................................................................................................657 C.6.4. Archivo main.c...............................................................................................................695 C.7. Especificacin del cdigo fuente del firmware cargador......................................................695 C.7.1. Archivo config.h............................................................................................................696 C.7.2. Archivo common.h........................................................................................................697 C.7.3. Archivo common.c.........................................................................................................697 C.7.4. Archivo serial.h..............................................................................................................697 C.7.5. Archivo serial.c..............................................................................................................697 C.7.6. Archivo interrupts.h.......................................................................................................697 C.7.7. Archivo interrupts.c.......................................................................................................698 C.7.8. Archivo memory.h.........................................................................................................699 C.7.9. Archivo memory.c.........................................................................................................700 C.7.10. Archivo boot.c..............................................................................................................706 C.8. Especificacin del cdigo fuente comn utilizado por el firmware del modem PLC y el firmware cargador.........................................................................................................................707 C.8.1. Archivo common.h........................................................................................................708 FernandoArielBeunza79156 13

Tesis de Grado en Ingeniera Informtica C.8.2. Archivo common.c.........................................................................................................710 C.8.3. Archivo serial.h..............................................................................................................717 C.8.4. Archivo serial.c..............................................................................................................718 Apndice D: Interfaz C++................................................................................................................721 D.1. Descripcin...........................................................................................................................721 D.2. Cdigo fuente........................................................................................................................721 D.2.1. Archivo modplcapcpp.h (plataforma Windows)...........................................................721 D.2.2. Archivo modplcapcpp.h (plataforma Linux).................................................................727 Apndice E: Interfaz Simulink.........................................................................................................733 E.1. Descripcin...........................................................................................................................733 E.2. Biblioteca de bloques Simulink............................................................................................733 E.3. Cdigo fuente........................................................................................................................736 E.3.1. Archivo modplc_simulink.c...........................................................................................737 E.3.2. Archivo MODEM_PLC_INTERFACE.C.....................................................................749 E.3.3. Archivo MODEM_PLC_CREATE_MESSAGE.C.......................................................751 E.3.4. Archivo MODEM_PLC_PUT_FIELD.C.......................................................................754 E.3.5. Archivo MODEM_PLC_SEND_MESSAGE.C............................................................756 E.3.6. Archivo MODEM_PLC_RECEIVE.C...........................................................................759 E.3.7. Archivo MODEM_PLC_GET_FIELD.C......................................................................761 E.3.8. Archivo MODEM_PLC_REAL_TIME.C.....................................................................764 Apndice F: Implementacin del dispositivo cliente........................................................................767 F.1. Descripcin del dispositivo...................................................................................................767 F.2. Implementacin del dispositivo.............................................................................................767 F.3. Cdigo fuente........................................................................................................................771 Apndice G: Implementacin de pruebas.........................................................................................775 G.1. Descripcin...........................................................................................................................775 G.2. Red de prueba implementada................................................................................................775 G.3. Modelo Simulink de prueba..................................................................................................778 G.4. Aplicaciones C/C++ de prueba.............................................................................................778 G.4.1. Plataforma Windows.....................................................................................................779 G.4.1.1. Archivo testphy.c....................................................................................................779 G.4.1.2. Archivo testap.c......................................................................................................783 G.4.1.3. Archivo testapcpp.cpp............................................................................................785 G.4.2. Plataforma Linux...........................................................................................................788 G.4.2.1. Archivo testphy.c....................................................................................................788 G.4.2.2. Archivo testap.c......................................................................................................792 G.4.2.3. Archivo testapcpp.cpp............................................................................................794 Glosario............................................................................................................................................799

14

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

1. Introduccin
Desde hace algunos aos se estn empleando buses de datos en aplicaciones integradas por diversos dispositivos que necesitan estar intercomunicados entre s para llevar a cabo las tareas para los cuales fueron diseados. Un ejemplo de esto son los automviles, que debido al aumento de la cantidad de componentes electrnicos utilizados, cada vez resulta ms dificultoso emplear interconexiones dedicadas debido al gran volumen de cables requeridos para interconectar todos los dispositivos entre s. En la actualidad se trabajan con redes como CAN, J1850, entre otras; por la cual, los dispositivos se intercomunican enviando mensajes entre s por medio de un bus de datos comn, eliminando la necesidad de que cada dispositivo tenga una conexin dedicada con cada uno de los dispositivos con los cuales necesita comunicarse. Esto ya reduce el volumen de conductores utilizados, pero puede reducirse an ms debido a que todava se encuentran presentes dos redes diferentes de cableado: una para datos y una para alimentacin. Esta razn es la que motiva la idea de utilizar comunicaciones PLC, en las cuales la alimentacin y la informacin comparte un mismo canal: la red de alimentacin; por el cual los dispositivos que necesariamente deben conectarse a la red de alimentacin para poder funcionar, pueden aprovechar la misma para intercambiar mensajes entre s. Existen diversos antecedentes que fundamentan esta idea de los cuales se pueden destacar: el DC-BUS [Maryanka00] desarrollado por la empresa Yamar Electronics Ltd. y trabajos realizados sobre comunicaciones PLC por la Facultad de Ingeniera Elctrica de la Universidad Tcnica Checa de Praga. Estos trabajos ponen su atencin en las capas fsica y de enlace, propuestas por el modelo OSI, dejando de lado la implementacin de las restantes capas. EL objetivo de ste trabajo es desarrollar un sistema prototipo que implemente las capas del modelo OSI no implementadas por los antecedentes mencionados anteriormente, y con esto, analizar la viabilidad de aplicar la ciencia de la informtica como complemento a la electrnica existente con la finalidad de aumentar funcionalidad y disminuir costos de implementacin. Para llevar a cabo dicho anlisis, el presente trabajo se encuentra organizado de la siguiente manera:

En el captulo 2 se realiza un anlisis del estado del arte del tema tratado en ste trabajo. Se comienza con la descripcin de los orgenes y evolucin de la tecnologa PLC en general, luego se presentan los estndares de comunicacin utilizados en la actualidad en aplicaciones para automviles, y finalmente se trata en mayor profundidad la tecnologa PLC aplicada al ambiente automotriz. En el captulo 3 se detalla el problema que se pretende resolver. Los antecedentes estudiados en el captulo anterior dejan la posibilidad de continuar avanzando en la materia, planteando diversos problemas a resolver. ste captulo presenta el problema de las capas del modelo OSI no implementadas, y define los requerimientos que debe cumplir el sistema para resolver el problema planteado. En el captulo 4 se propone un sistema prototipo que cumpla con los requerimientos definidos en el captulo anterior. Se realiza una descripcin del diseo del sistema prototipo capa por capa, siguiendo el modelo planteado por OSI. En el captulo 5 se evala el cumplimiento de lo requerimientos planteados en el captulo 3. Se compara el sistema prototipo propuesto con otras alternativas existentes, realizando

FernandoArielBeunza79156

15

Tesis de Grado en Ingeniera Informtica una evaluacin del diseo expuesto en el captulo 4 frente a las alternativas enumeradas en el captulo 2.

En el captulo 6 se detallan las conclusiones extradas a partir de la evaluacin mencionada anteriormente. Se describen los xitos y dificultades del diseo propuesto en el presente trabajo, y se abren futuras lneas de investigacin.

16

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

2. Antecedentes
En ste captulo se describe la evolucin de la tecnologa PLC desde sus orgenes hasta la actualidad. En la primer parte se presentan los estndares utilizados en infraestructura edilicia, que fueron los destinatarios iniciales de la sta tecnologa. En la segunda parte, se trata especficamente la adaptacin de la tecnologa PLC al ambiente del automvil. Para finalizar, se presentan los estndares que utilizan los automviles en la actualidad, que no utilizan la tecnologa PLC, pero plantean soluciones a problemas propios de ste entorno, que pueden tenerse en cuenta para adaptar la tecnologa PLC al ambiente automotriz.

2.1. Tecnologa PLC


La idea de transmitir informacin sobre un medio ya existente destinado a brindar otro servicio, se remonta a la dcada del 30, cuando Alemania utiliz la red de telefona para brindar el servicio de radio por cable llamado HF-Drahtfunk [HF-Drahtfunk]. ste sistema le brindaba al usuario el servicio de telefona y radio, en forma simultnea, cosa que no ocurra en sistemas anteriores similares. Suiza contaba con un sistema similar, llamado Telefonrundspruch [Linjesender], debido a que su geografa montaosa no permita una cobertura nacional por medio de radio inalmbrica. La primera vez que se implement la tecnologa PLC fue para brindar el mismo servicio de radio que brindaban Alemania y Suiza. En ste caso, en vez de utilizar las lneas telefnicas disponibles, se decidi utilizar las lneas elctricas para la transmisin de voz. Gran Bretaa realiz experimentos con este sistema, pero la Unin Sovitica fue la que adopt ste medio para la difusin de programas de radio. Tambin lo hizo Noruega, el servicio en ste pas fue llamado Linjesender [Linjesender]. Todos los sistemas anteriormente mencionados en la actualidad ya no existen, HFDrahtfunk desapareci en 1967, Linjesender lo hizo en 1987 y Telefonrundspruch en 1997; pero demostraron que era posible la transmisin de informacin utilizando redes ya existentes. HFDrahtfunk y Telefonrundspruch, fueron los precursores de los servicios de banda ancha que se brindan hoy en da; mientras que el sistema sovitico y Linjesender, son los precursores de la tecnologa PLC que hoy en da no tiene tanta difusin que la anterior, pero cada da est cobrando ms relevancia debido al alcance que tiene la red elctrica frente a otras. La tecnologa PLC fue adoptada por las compaas de electricidad para transmisin de datos a baja velocidad. En la dcada del 50 crearon un sistema que permita a las compaas controlar el consumo, el encendido del alumbrado pblico y el valor de las tarifas elctricas por medio de una seal de baja frecuencia. A fines de la dcada del 80, se logr realizar transmisiones de datos bidireccionales; y a fines de la dcada del 90, se pudo elevar la velocidad de transmisin. sto instal la idea de poder utilizar la red elctrica para brindar servicios de voz y datos. En la actualidad, compaas como DS2, disean chips capaces de alcanzar velocidades de transmisin que rondan los 200 Mbps sobre lneas de baja y media tensin, para aplicaciones dentro de un hogar o una oficina y de ltima milla [Alcar07].

FernandoArielBeunza79156

17

Tesis de Grado en Ingeniera Informtica

2.1.1. X10
ste estndar fue desarrollado para controlar de forma remota dispositivo elctricos en un hogar u oficina. Para la transmisin de datos utiliza como medio fsico las lneas elctricas presentes en cualquier establecimiento.

2.1.1.1. Mtodo de transmisin


Las transmisiones son sincronizadas por el punto de cruce por cero de la seal que proporciona energa (senoidal de 50 o 60 Hz). La informacin se enva por medio de rfagas de pulsos de 120 KHz durante un semiciclo de la seal que proporciona energa, empleando la siguiente codificacin: la presencia de un pulso en un semiciclo y la ausencia del mismo en el siguiente, representa un uno lgico; en cambio, la ausencia de un pulso en un semiciclo seguido de la presencia del mismo en el siguiente semiciclo, representa un cero lgico. A continuacin, en la figura 2.1 se puede observar el esquema de codificacin anterior.

Figura 2.1. Codificacin de bits utilizada por el protocolo X10 [X10SignalTheory].

Para permitir el uso del protocolo en instalaciones de red trifsica, se transmiten tres pulsos que coinciden cada uno de ellos con el cruce por cero de las seales de potencia de cada una de las fases, como se puede observar en la figura 2.2.

Figura 2.2. Transmisin sobre red trifsica [X10SignalTheory].

18

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica El mecanismo de codificacin de los bits de informacin implementado por X10, permite una velocidad de transmisin equivalente a la frecuencia de la seal de potencia utilizada para sincronizacin, si la frecuencia es de 50 Hz la velocidad es de 50 bps, en cambio si la frecuencia es de 60 Hz la velocidad es de 60 bps.

2.1.1.2. Estructura de mensaje


La estructura de un mensaje se encuentra conformada por cuatro campos utilizados para marcar el comienzo de un mensaje, identificar el lugar (casa) donde se encuentra el dispositivo al cual se le quiere enviar el comando, identificar el dispositivo o la funcin, y por ltimo marcar el fin del mensaje (ver figura 2.3). El tamao de un mensaje es de 11 bits, que corresponden a 11 ciclos de la seal de potencia.
Start Cdigo Cdigo de Bit code de casa dispositivo/funcin de fin 2 bits 4 bits 4 bits 1 bit

Figura 2.3. Estructura de un mensaje X10.

Cada bit mencionado en la figura anterior corresponde a dos semiciclos de la seal de potencia. Un ejemplo de como se transmite un mensaje puede observarse en la figura 2.4, en donde se muestran los bits enviados (arriba de la seal) junto con su codificacin (abajo de la seal).

Figura 2.4. Ejemplo de comando X10 [X10SignalTheory].

Un comando X10 generalmente involucra dos mensajes: uno para la activacin del dispositivo destinatario, seguido de otro que le indica al dispositivo destinatario la accin que debe ejecutar. El comando de la figura anterior corresponde a la activacin del dispositivo 2 ubicado en la casa A. En el primer mensaje, se identifica la casa y el dispositivo al cual se le desea dar la orden; en cambio, en el segundo mensaje se indica la orden. El bit final de cada mensaje es utilizado para indicar que a continuacin se transmitir otro mensaje (bit cero) o para dar fin a la secuencia de mensajes (bit uno).

2.1.1.3. Esquema de direccionamiento


Para hacer referencia al lugar donde se encuentra el dispositivo destinatario se emplea el cdigo de casa. Cada casa se identifica por medio de una letra que se codifica por medio de una secuencia de bits, como se indica en la tabla 2.1.

FernandoArielBeunza79156

19

Tesis de Grado en Ingeniera Informtica

Letra Cdigo de casa A B C D E F G H 0110 1110 0010 1010 0001 1001 0101 1101

Letra Cdigo de casa I J K L M N O P 0111 1111 0011 1011 0000 1000 0100 1100

Tabla 2.1. Cdigos de casa [X10TechNote].

De similar forma, el cdigo de dispositivo simplemente corresponde a un nmero entre 0 y 15. Este esquema permite trabajar con 256 dispositivos sobre una misma lnea de alimentacin, a razn de 16 dispositivos como mximo por casa, con un mximo de 16 casas.

2.1.2.4. Funciones
Las funciones que pueden proveer un dispositivo se codifican por medio de 4 bits. Su codificacin se encuentra detallada en la tabla 2.2, que se encuentra a continuacin:
Cdigo 0000 0001 0010 0011 0100 0101 0111 1000 1001 101x 1100 1101 1110 1111 Funcin All units Off All lights On On Off Dim Bright Extended Code Hail Request Pre-Set Dim Extended Data Status is On Status is Off Status Request Descripcin Desconecta todos los dispositivos con el cdigo de casa indicado en el mensaje. Conecta todos los dispositivo de iluminacin (con capacidad de control de brillo). Conecta un dispositivo. Desconecta un dispositivo. Reduce la intensidad luminosa. Aumenta la intensidad luminosa. Cdigo de extensin. Solicita respuesta de los dispositivos con cdigo de casa indicado en el mensaje. Permite seleccionar dos niveles de intensidad luminosa predefinidos. Datos adicionales (seguido por 8 bytes). Respuesta a un pedido de Status Request, indicando que el dispositivo est conectado. Respuesta a un pedido de Status Request, indicando que el dispositivo est desconectado. Pedido solicitando el estado del dispositivo.

Hail Acknowledge Respuesta a un comando anterior.

Tabla 2.2. Lista de funciones definidas por X10 [X10SignalTheory].

Las funciones ms utilizadas son las seis primeras de la tabla anterior. Las funciones Hail Request y Hail Acknowledge, se utilizan para comunicacin con casas vecinas. Las funciones Extended Code y

20

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica Extended Data son empleadas para expandir la capacidad de comandos y de enviar datos adicionales, respectivamente.

2.1.2. CEBus
El estndar CEBus implementa un modelo de comunicaciones punto a punto, en donde cualquier nodo puede comunicarse con otro en cualquier instante. La comunicacin se realiza a travs de un nico medio compartido, utilizando un protocolo de control de acceso al medio para resolver las colisiones cuando dos o ms dispositivos quieren acceder al medio fsico en forma simultnea. CEBus fue pensado para trabajar sobre diversos medios fsicos: lneas de potencia, par trenzado, coaxil, radio e infrarrojo. En el presente trabajo slo se trata el primer medio fsico, aunque muchos conceptos son aplicables tambin a los otros medios. ste estndar implementa cuatro de las siete capas definidas por el modelo OSI, que son: la capa fsica, la capa de enlace, la capa de red y la capa de aplicacin. Sobre la capa de aplicacin se encuentra CAL, que establece un lenguaje comn para permitir la interoperabilidad entre dispositivos.

2.1.2.1. Mtodo de transmisin


La capa fsica de CEBus se basa en una tecnologa de espectro ensanchado patentada por la empresa Intellon. La tcnica empleada es diferente a la tecnologa tradicional, ya que el smbolo utilizado es una seal conocida como Chirp. Una seal Chirp se genera a partir de un barrido en frecuencia, dentro de un rango determinado, de una seal senoidal, y se caracterizan por presentar un alto rechazo a interferencias. La seal Chirp empleada por CEBus (figura 2.5) comienza con una seal senoidal de 200 KHz y aumenta hasta los 400 KHz, para luego saltar a 100 KHz y avanzar hasta 200 KHz nuevamente. sta seal se genera por medio de un sintetizador a partir de una tabla compuesta por 360 muestras.

Figura 2.5. Seal Chirp utilizada por CEBus [Montoya06].

Un paquete de datos se transmite utilizando la seal Chirp anterior. La primer secuencia de seales Chirp constituye el prembulo del paquete y es utilizado por los transmisores para resolver FernandoArielBeunza79156 21

Tesis de Grado en Ingeniera Informtica quien tiene derecho a uso del canal de comunicacin. Luego del prembulo, el transmisor que gan el derecho de utilizar el canal de comunicacin, transmite un conjunto de seales Chirp para marcar el comienzo del paquete. Para recuperar los bits del paquete, los receptores se sincronizan aplicando la operacin de correlacin a la seal recibida. Cuando la seal recibida coincide con la seal Chirp esperada, la correlacin devuelve un pulso de sincronismo. CEBus con el mecanismo de transmisin expuesto, puede lograr velocidad de transmisin de 10 kbps.

2.1.2.2. Estructura de paquete


Un paquete CEBus se encuentra constituido fundamentalmente por las siguientes partes: un prembulo, una unidad de datos del protocolo de capa de enlace, llamado LPDU, y un cdigo CRC. La LPDU puede contener como mximo 41 bytes, y se conforma de un encabezado (9 bytes) y una unidad de datos del protocolo de red, llamado NPDU. La NPDU puede contener hasta 32 bytes, de los cuales uno pertenece al encabezado y el resto se destina a la unidad de datos del protocolo de aplicacin, llamado APDU. El APDU se compone de un encabezado de 1 byte de longitud y el resto se destina a instrucciones de la CAL.

Figura 2.6. Estructura de un paquete CEBus [House].

El encabezado de la LPDU contiene un campo de control (1 byte), con informacin de control, como el nmero de secuencia del paquete, la prioridad del mismo y el tipo. Tambin contiene la direccin de destino del paquete como la de origen del mismo (4 bytes cada una). El encabezado de la NPDU contiene informacin acerca del encaminado del paquete y fragmentacin del mismo. El encabezado de la APDU contiene informacin sobre como debe responder el receptor cuando recibe un paquete.

2.1.2.3. Esquema de direccionamiento


El esquema de direccionamiento propuesto por CEBus, utiliza 32 bits para representar las direcciones de los dispositivos, lo que se traduce en 232 direcciones posibles. Dichos 32 bits se dividen en dos grupos de 16 bits cada uno: el primer grupo se lo designa direccin de sistema (o cdigo de hogar), y el segundo grupo se lo designa direccin MAC (o cdigo de unidad). Cada una de las direcciones anteriores presenta un rango de direcciones utilizables comprendido entre 1 y 65535. El identificador de cdigo de unidad 0 se reserva para broadcast 22 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica dentro de un grupo de dispositivos asociado a un cdigo de hogar. Si el identificador de cdigo de hogar tambin es 0, el broadcast incluye a todos los dispositivos de la red sin importar a que cdigo de hogar se encuentren asociados.

2.1.2.4. Lenguaje de aplicacin


CAL implementa un modelo jerrquico para describir a cada nodo de la red. Un nodo puede tener varios contextos, y a su vez, cada contexto puede estar compuesto por varios objetos. Los objetos pueden tener varias variables de instancia. Todo dispositivo presenta un contexto universal (que se identifica con el cdigo 00). La funcin de ste contexto es la de controlar la presencia de cada dispositivos dentro de la red. El contexto universal presenta dos objetos: el objeto de control de nodo (conocido como objeto 0) y el objeto de control de contexto (objeto 1). El objeto de control de nodo contiene una serie de variables de instancia con informacin acerca del dispositivo (direcciones, fabricante, etc.). El objeto de contexto presenta una nica variable de instancia que contiene una lista de identificadores de objeto del contexto. Adems del contexto universal, los dispositivos pueden presentar varios contextos adicionales, con mltiples objetos por contexto, dependiendo de las funcionalidades que provean los dispositivos. En la tabla 2.3 se pueden observar un conjunto de objetos definidos, cada uno de ellos con sus propias variables de instancia.
Valor (Hex) 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D Nombre Node Control Context Control Data Channel Receiver Data Channel Transmitter Binary Switch Binary Sensor Analog Control Analog Sensor Multi-position Switch Multi-state Sensor Matrix Switch Multiplane Switch Gagned Analog Control Valor (Hex) 0E 0F 10 11 13 14 15 16 17 19 1A 1C 1D Meter Display Medium Transport Dialer Keypad List Memory Data Memory Motor Synthesizer/Tuner Tone Generator Counter Clock Nombre Gagned Analog Control

Tabla 2.3. Objetos definidos por CEBus [House].

Para acceder a las variables de instancia de cada objeto, CAL define un conjunto de mtodos enumerados en la tabla 2.4.

FernandoArielBeunza79156

23

Tesis de Grado en Ingeniera Informtica

Valor 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 52 53 54 55 56 57 58 59 5A

Nombre nop setOFF setON getValue getArray setValue setArray add increment subtract compare comparei swap exit alias inherit disinherit if do while repeat build IV IV IV

Parmetros

Tipos de datos B B BNC D BNC D N N N N BNCD BNCD BNCD BNCD

IV [, [<offset>], <count>] IV IV [, [<offset>], <data>] IV1, IV2, [IV3] IV [, <number>] IV1, IV2, [IV3] IV1, IV2 IV1, <data> IV1, IV2 [<error number>] <alias ID> [<string>] IV, <value> IV, <value> <boolean> BEGIN <message list> [else clause] END <boolean> BEGIN <message list> END <boolean> BEGIN <message list> END <boolean> BEGIN <message list> END <macro ID> BEGIN <message list> END

decrement IV [, <number>]

copyValue IV1, IV2 [, <context>, <object>]

D D

Tabla 2.4. Mtodos definidos por CEBus [House].

Los tipos de datos definidos por CAL son: cadenas de caracteres (strings), datos, nmeros y booleanos. En la tabla 2.4 se aclaran los tipos de datos que puede manipular cada mtodo. Por ltimo, CAL tambin define una lista de posibles errores que pueden ocurrir, que se detallan en la tabla 2.5.

24

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Valor 0 1 2 3 4 5 6 7 8 9

Descripcin Unknown Context ID Unknown Object ID Unknown Method ID Unknown IV Label Malformed Expression Macro not defined Alias not defined Syntax error Resource in use Command too Complex

Valor 10 11 12 13 14 15 16 17 18 19

Descripcin Inherit Disabled Value out of Range Bad Argument Type Power Off Invalid Argument IV Read Only No Default Cannot Inherit Resource Precondition Complete Application Busy

Tabla 2.5. Cdigos de error definidos por CEBus [House].

2.1.3. CENELEC 50065


La norma que regula las comunicaciones PLC en Europa se la conoce como CENELEC 50065-1. sta norma es la encargada de definir el rango de frecuencias que puede ser utilizado para este tipo de comunicaciones, las amplitudes mximas de las seales y los lmites de interferencia entre las bandas circundantes. Se definen cuatro bandas para distintas aplicaciones, como se puede observar en la tabla 2.6.
Banda Rango de frecuencias 3 KHz 9 KHz A B C D 9 KHz 95 KHz 95 KHz 125 KHz 125 KHz 140 KHz Propsito Para uso de las compaas de distribucin elctrica solamente. Para uso de las compaas de distribucin elctrica y sus licencias. Disponible para los consumidores sin restricciones. Disponible para los consumidores con control de acceso al medio

140 KHz 148.5 KHz Disponible para los consumidores sin restricciones.

Tabla 2.6. Rango de frecuencias establecido por CENELEC 50065-1 [Kaspar].

Cuando se trabaja dentro de la banda A, la norma no exige la utilizacin de protocolos de acceso al medio. Del mismo modo ocurre con la banda B, destinada a ser utilizada por dispositivos tales como intercomunicadores. En cambio, la banda C debe utilizar algn mtodo de control de acceso al medio; ya que fue pensada en escenarios en donde las transmisiones simultneas son altamente improbables, como por ejemplo comunicaciones internas entre computadoras. Por ltimo, la banda D presenta caractersticas similares a la A, por lo cual pueden existir colisiones si dos dispositivos transmiten en simultneo [PLCEc].

FernandoArielBeunza79156

25

Tesis de Grado en Ingeniera Informtica

Figura 2.7. Diferencias entre norma europea y norteamericana [Kaspar].

Como se observa en la figura 2.7, a diferencia de Europa, Estados Unidos y Japn tienen un lmite superior para el rango de frecuencias destinado para comunicaciones PLC, debido a que stos ltimos no utilizan sistemas de radio de onda larga. La norma tambin define las amplitudes mximas que pueden presentar las seales utilizadas para transmitir la informacin. A continuacin en la figura 2.8, se pueden observar dichos niveles para cada una de las bandas establecidas.

Figura 2.8. Lmites mximos de nivel de seal permitidos por CENELEC 50065-1 [PLCEc].

Como se puede apreciar, para la banda A, el nivel mximo permitido alcanza los 134 dBuV en 9 KHz y desciende hasta los 120 dBuV en el lmite superior de la banda en 95 KHz. El resto de las bandas tiene un nivel mximo permitido de 122 dBuV.

2.1.4. UPB
El estndar UPB es una evolucin de X10, que utiliza la misma tcnica de transmisin de informacin, agregando a la seal de potencia que alimenta a los dispositivos de la red elctrica, la

26

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica seal de informacin. ste estndar introduce algunas mejoras respecto a X10, como el mtodo de modulacin que permite elevar la velocidad de transmisin, y tambin expande la capacidad de direccionamiento de los dispositivos.

2.1.4.1. Mtodo de transmisin


UPB utiliza como seal de sincronizacin la seal de potencia utilizada para alimentacin (seal senoidal de 50 o 60 Hz), tomando como referencia el cruce por cero de sta seal con flanco ascendente. A diferencia de X10, el pulso no se transmite luego del cruce por cero, sino que en ste caso se espera un tiempo determinado para iniciar la transmisin. Luego, el siguiente pulso, es transmitido cuando transcurre medio ciclo de seal de sincronizacin (seal de potencia). ste estndar tiene la capacidad de transmitir ms bits en un semiciclo de seal de sincronizacin que el estndar X10, ya que emplea la modulacin PPM, que permite codificar dos bits por semiciclo como se puede observar en la figura 2.9.

Figura 2.9. Codificacin de bits utilizada por el protocolo UPB [UPB03].

Para enviar los dos bits es emplean 800 microsegundos divididos en cuatro fragmentos de 200 microsegundos cada uno. El fragmento en el cual se emite el pulso depende del valor que tome el grupo de dos bits que se desean transmitir. Con este esquema de codificacin, un byte de informacin puede ser enviado en cuatro semiciclos de la seal de potencia. La velocidad de transferencia lograda de sta forma equivale a cuatro veces la frecuencia de la seal de potencia utilizada para sincronizacin: 200 bps (para 50 Hz) y 240 bps (para 60 Hz).

FernandoArielBeunza79156

27

Tesis de Grado en Ingeniera Informtica

2.1.4.2. Estructura de paquete


La estructura de paquete propuesta por el UPB, presenta longitud variable, y se compone de los siguientes campos: un prembulo de longitud fija de 1 byte, un encabezado de 5 bytes, el mensaje cuya longitud puede variar entre 0 y 18 bytes, una suma de verificacin de 1 byte, y la confirmacin de recepcin de un bit de longitud.

Figura 2.10. Estructura de un paquete UPB [UPB03].

El prembulo del paquete es utilizado por los receptores para realizar ajustes que le permitan tener una buena recepcin del resto del paquete. El encabezado contiene cierta informacin de control, como el dispositivo que dio origen al paquete, su destinatario, el tamao del mismo, entre otros. La composicin del encabezado se detalla en la figura 2.11.

Figura 2.11. Estructura del encabezado de un paquete UPB [UPB03].

El campo CTL tiene una longitud de 2 bytes, y es utilizado para indicar el tamao del paquete, como debe ser recibido el mismo, como se debe responder al mismo y la cantidad de veces que fue enviado. El campo NID tiene una longitud de 1 byte, y permite identificar la red en la cual se encuentra el destinatario del paquete. El campo DID, de 1 byte de longitud, permite identificar al dispositivo destinatario del paquete. El campo SID, de 1 byte de longitud, indica el dispositivo que envi el paquete. Luego del encabezado se encuentra el mensaje cuya longitud puede ser de 0 hasta 18 bytes. El mensaje se compone (figura 2.12) de dos campos identificados como MDID y MDA.

28

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Figura 2.12. Estructura del mensaje de un paquete UPB [UPB03].

El campo MDID, de 1 byte de longitud, es utilizado para identificar un comando o una respuesta a un comando. El campo MDA puede contener hasta 17 bytes y es el encargado de transportar los argumentos asociados a un comando o una respuesta a un comando. A continuacin del mensaje, se encuentra la suma de verificacin que es utilizada por el destinatario del paquete para determinar si el mismo fue recibido correctamente o presenta errores. Por ltimo, el bit de confirmacin de recepcin, es un bit que deja disponible en dispositivo que dio origen al paquete, para que el destinatario pueda indicar al origen si el paquete fue recibido correctamente o no.

2.1.4.3. Esquema de direccionamiento


El protocolo UPB permite crear redes virtuales sobre una misma red fsica. El estndar permite un mximo de 255 redes. sto permite agrupar los distintos dispositivos en distintas redes virtuales sobre una misma lnea de alimentacin. Cada una de las redes virtuales puede contener hasta 250 dispositivos. El concepto es similar al propuesto por X10, pero con una mayor capacidad, ya que el esquema propuesto por UPB puede soportar hasta 63750 dispositivos sobre una misma lnea, mientras que X10 solo soporta 256. Los identificadores de red vlidos se encuentran comprendidos en el rango de 1 a 255, reservando el identificador 0 para mensajes de broadcast. El identificador 0 le permite a cualquier dispositivo poder enviar mensajes a todos los dispositivos conectados en la lnea independientemente de la red a la cual pertenezcan, ya que cada dispositivo slo recibe los mensajes pertenecientes a su red. Los identificadores de dispositivo se encuentran comprendidos en el rango de 1 a 250, reservando el identificador 0 para mensajes de difusin dentro de la red virtual, y los identificadores comprendidos entre 251 y 255 para propsitos especiales. Una funcionalidad adicional que brinda UPB, es la posibilidad de crear grupos de dispositivos, que respondan a los comandos enviados que contengan como identificador de dispositivo destino, el identificador de grupo al pertenecen los dispositivos. El rango de identificadores de grupo vlidos es el mismo al utilizado para los identificadores de direcciones (1 a

FernandoArielBeunza79156

29

Tesis de Grado en Ingeniera Informtica 250), descartando el identificador 0 (identificador de broadcast) y el rango de 251 a 255 (propsitos especiales).

2.1.4.4. Comandos
La variedad de comandos que brinda UPB es mucho ms amplia que los proporcionados por X10. La mxima cantidad de comandos soportados es de 256 (frente a los 16 de X10), aunque no se utilizan todos los identificadores disponibles. En la tabla 2.7 se hace referencia a los comandos principales implementados por UPB:
MDID (Hex) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D Null Write Enable Write Protect Start SETUP Mode Stop SETUP Mode Get SETUP Time Auto-Address Get Device Status Set Device Control Get Signal Strength Get Noise Level Add Link Delete Link Transmit This Message Comando MDID (Hex) 0E - 0F Unused 10 11 12 13 14 15 16 17 18 19 1A Get Register Value Set Register Value Copy Register Value Swap Register Nibbles Increment Register Value Decrement Register Value Left Shift Register Right Shift Register Set Register Bits Clear Register Bits Toggle Register Bits Comando

1B - 1F Unused

Tabla 2.7. Comandos principales implementados por UPB [UPB03].

Tambin existen una serie de comandos y respuestas especiales dedicados a funciones de control, como se puede ver en la tabla 2.8.
MDID (Hex) 20 21 22 23 24 Comando / Respuesta Activate Link Deactivate Link Goto Start Fade Stop Fade MDID (Hex) 25 30 31 Comando / Respuesta Blink Report State Store State

26 - 2F Unused

32 - 3F Unused

Tabla 2.8. Comandos y respuestas especiales implementados por UPB [UPB03].

Por ltimo, UPB define una serie de respuestas a comandos que se detallan en la tabla 2.9.

30

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

MDID (Hex) 80 -84 Unused 85 86 87 89 8A

Respuesta

MDID (Hex) 90 91 92 93 AF

Respuesta Register Values RAM Values Raw Data Heartbeat Acknowledgement

Setup Time Device State Device Status Signal Strength Noise Level

94 - AE Unused

8B - 8F Unused

Tabla 2.9. Respuestas implementados por UPB [UPB03].

2.1.5. LonWorks
ste estndar se basa en el esquema propuesto por LON, que consisten en un conjunto de dispositivos que se conectan por medio de uno o varios medios fsicos, y emplean para comunicarse un protocolo comn. Cada dispositivo tiene la capacidad de generar acciones en respuesta a mensajes recibidos de otros dispositivos, y/o generar mensajes ante el cumplimiento de determinadas condiciones.

2.1.5.1. Protocolo CNP


Del mismo modo que las redes de datos e internet se basan en el protocolo TCP/IP [RFC793] [RFC791], LonWorks se basa en el protocolo CNP [ISO/IEC14908-1]. ste ltimo protocolo fue diseado para cubrir los requerimientos de las aplicaciones de control. ste protocolo implementa siete capas siguiendo las recomendaciones sugeridas por el modelo OSI. El propsito y servicios que provee cada una de las capas definidas se describe en la tabla 2.10.

FernandoArielBeunza79156

31

Tesis de Grado en Ingeniera Informtica

Capas OSI Fsica

Propsito Interconexin elctrica

Servicios provistos Medios fsicos. Esquemas de modulacin. Armado y desarmado de tramas. Verificacin de errores. Control de acceso al medio. Prioridad. Comunicaciones unicast y multicast. Encaminado de mensajes.

Enlace

Acceso al medio y armado de tramas

Red

Envo de mensajes

Envo de mensajes con o sin confirmacin de recepcin. Transporte Confiabilidad en el envo de mensajes Ordenamiento de mensajes. Deteccin de mensajes duplicados. Sesin Control Pedido y respuesta. Autenticacin. Variables de red. Mensajes de aplicacin. Configuracin de red. Diagnstico de red. Transferencia de archivos. Configuracin de aplicaciones. Especificacin de aplicaciones. Alarmas. Registro de datos. Planificacin.

Presentacin Interpretacin de datos

Aplicacin Compatibilidad

Tabla 2.10. Capas CNP [Echelon99].

La organizacin de los datos para el transporte de los mismos, en cada una de las capas presentadas anteriormente se detallan en la tabla 2.11.
Capa Fsica Enlace Red Transporte Sesin Aplicacin Organizacin de datos Bits en bruto Trama Datagrama Paquete de transporte Paquete de sesin Mensaje

Presentacin Paquete de presentacin

Tabla 2.11. Organizacin de datos utilizada por cada capa [Echelon99].

2.1.5.2. Capa fsica


La capa fsica se encarga de definir como se transmiten los bits de datos en bruto sobre un determinado medio fsico. El protocolo CNP fue diseado para ser independiente del medio fsico, lo que permite que LonWorks pueda ser implementado sobre diferentes tipos de redes.

32

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica Los diferentes tipos de medio que pueden utilizarse permiten comunicaciones bidireccionales entre cualquiera de los dispositivos conectados a la red. En la tabla 2.12 se detallan cada uno de los medios fsicos con los cuales LonWorks puede trabajar.
Nombre IP-852 PL-20A PL-20C PL-20N TP/FT-10 Medio IP-852 Tunneling CENELEC A-band Power Line CENELEC C-band Power Line w/access protocol CENELEC C-band Power Line w/o access protocol Free Topology Twisted Pair Velocidad N/A 2613bps 156.3k/3987bps 156.3k/3987bps 78.13kbps 1.25Mbps Definicin ISO/IEC 14908-4 ISO/IEC 14908-3 ISO/IEC 14908-3 ISO/IEC 14908-3 ISO/IEC 14908-2 LONMARK Interoperability Guidelines

TP/XF-1250 Transformer-Isolated Twisted Pair

Tabla 2.12. Organizacin de datos utilizada por cada capa [Echelon99]. El objetivo del presente trabajo no es tratar todos los medios fsicos sobre los cuales puede implementarse LonWorks sino que analizar los medios relacionados con las lneas de potencia, cuyos nombres (segn tabla 2.12) son PL-20A, PL-20C y PL-20N. Las velocidad de transferencia que se pueden alcanzar depende del medio fsico sobre el cual se trabaje. Como se puede observar en la tabla 2.12, cuando se trabajan con lneas de potencia, se obtienen las velocidades de transferencia ms bajas comparadas con los otros medios fsicos existentes. LonWorks, sobre lneas de potencia, puede trabajar dentro del rango de frecuencias pertenecientes a la banda A y a la banda C definidas por CENELEC 50065-1. El sistema de modulacin utilizado es BPSK combinado con espectro ensanchado de banda estrecha [Montoya06], que para el caso de la banda A, el rango de frecuencias utilizado se extiende desde los 75 KHz hasta 86 KHz; mientras que para el caso de la banda C, el rango de frecuencias se extiende comprende desde los 115 KHz hasta los 132 KHz.

2.1.5.3. Capa de enlace


El protocolo CNP define establece varios mecanismos para controlar el acceso al medio fsico, de los cuales se analizar el CSMA, dado que es el utilizado cuando se trabaja sobre lneas de potencia. Dentro de todas las variantes de CSMA, ste protocolo implementa una variante propia llamada p-persistente CSMA predictivo. El mecanismo consiste en que previo al envi de una trama, se establece un tiempo de espera (dividido en ranuras), y transcurrido dicho tiempo, si el medio se encuentra disponible, se enva la trama. La cantidad de ranuras que se deben esperar se establece en forma aleatoria, a partir de un conjunto de valores posibles, para evitar colisiones. La cantidad de valores de dicho conjunto se ajusta dependiendo de la actividad que haya sobre el medio fsico. Si el medio no es utilizado por ningn dispositivo, todos los dispositivos establecen 16 ranuras de espera, entre los cuales cada uno de los dispositivos que deseen enviar algo deber elegir en forma aleatoria cuantas ranuras esperar (entre 1 y 16). stas 16 ranuras de espera pueden aumentar, dependiendo del trfico de la red, para evitar colisiones, hasta un mximo de 63 ranuras El protocolo tambin ofrece la posibilidad de utilizar un sistema de prioridad para el envo de paquetes crticos. Dicho sistema de prioridad se basa en la introduccin de ranuras de tiempo

FernandoArielBeunza79156

33

Tesis de Grado en Ingeniera Informtica adicionales previo a las ranuras utilizados para evitar las colisiones. El nmero de ranuras destinadas a prioridad puede variar entre 0 y 127. Una trama se encuentra conformada por los siguientes campos: un prembulo, un encabezado con informacin de control, los datos (datagrama de capa de red), un cdigo de deteccin de errores y un indicador de final de trama.

Figura 2.13. Estructura de trama [Echelon99].

El prembulo es utilizado por los receptores para sincronicen sus relojes de modo de poder recibir la trama. ste se compone de dos campos llamados: un bit-sync y un byte sync. El primero consiste en 6 bits utilizados para sincronizacin, mientras que el segundo consiste en 1 bit que indica el fin del prembulo. El encabezado contiene tres campos: priority, path y delta backlog. El primer campo especifica la prioridad de trama. El segundo campo identifica a la medio fsico por el cual se envi la trama. Por ltimo, el tercer campo contiene informacin para el ajuste del tiempo de espera del mecanismo de acceso al medio. El cdigo de verificacin de errores se compone de un cdigo CRC de 16 bits, utilizado para determinar si la trama fue recibida sin errores.

2.1.5.4. Capa de red


La capa de red establece como se encaminan los paquetes de mensajes desde el origen de los mismos hasta el o los destinatarios. Tambin define los nombres y direcciones de los dispositivos. Los mensajes pueden enviarse a un destinatario, a un grupo de dispositivos o a todos los dispositivos. El nombre es un identificador nico utilizado para individualizar a un simple objeto dentro de una clase de objetos. ste es asignado al momento de la creacin del objeto y no se modifica durante la vida del objeto. Una direccin es un identificador nico que individualiza a un objeto o a un grupo de objetos dentro de una clase de objetos. A diferencia del nombre, una direccin puede ser modificada en todo momento. La direccin se compone de tres partes: dominio, subred y nodo. Tambin existe el Neuron ID, que es un identificador de 48 bits que puede ser utilizado como direccin, ya que es nico y es asignado en el momento de fabricacin del dispositivo, y no puede ser modificado. Un dominio es una coleccin lgica de dispositivos que pueden estar conectados a diferentes medios fsicos creando una red virtual, o bien pueden existir varias colecciones de dispositivos sobre un mismo medio fsico formando varias redes lgicas sobre un mismo medio. La cantidad de bytes utilizada para identificar un dominio puede configurarse en 0, 1, 3 o 6 bytes. Una subred es una coleccin lgica de dispositivos dentro de un dominio. Pueden existir hasta 255 subredes dentro de un dominio. Todos los dispositivos pertenecientes a una subred deben estar conectados al mismo segmento.

34

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica Un nodo es un identificador de dispositivo de 7 bits de longitud que permite individualizar un dispositivo dentro de una subred. Con ste esquema, una subred puede contener hasta 127 dispositivos. Un grupo es una coleccin de dispositivos dentro de un dominio, que a diferencia de una subred no importa donde se encuentre ubicados (pueden pertenecer a diferentes segmentos). Para identificar a los grupo se utiliza 1 byte, lo que permite tener hasta 256 grupos dentro de un mismo dominio. Existe diversos modos de direccionamiento, y segn cual sea utilizado, la cantidad de bytes requeridos. En la tabla 2.13 se describen los 5 modos de direccionamiento posibles.
Modo de direccionamiento Formato de direccin Destino Todos los dispositivos dentro del dominio Todos los dispositivos dentro de la subred Todos los dispositivos dentro del grupo Dispositivo especfico Tamao de la direccin 3 3 3 4 9

Broadcast dentro del dominio Dominio (Subred = 0) Broadcast dentro de la subred Dominio, Subred Multicast Unicast Neuron ID Dominio, Grupo Dominio, Neuron ID

Dominio, Subred, Nodo Dispositivo especfico dentro de una subred

Tabla 2.13. Modos de direccionamiento [Echelon99].

Un datagrama se encuentra conformado de los siguientes campos: versin, formato de paquete, formato de direccin, tamao del dominio, direccin, dominio y el paquete.

Figura 2.14. Estructura de datagrama [Echelon99].

La versin especifica la versin del protocolo, y siempre toma el valor cero. El formato del paquete especifica el formato del contenido del paquete, que puede ser: un paquete de transporte, un paquete de sesin, un paquete autenticado o un paquete de presentacin. El formato de la direccin indica que tipo de direccin contiene el paquete, pudiendo existir cuatro variantes: broadcast (subred), grupo, subred/nodo o grupo con confirmacin de recepcin, o Neuron ID. El tamao del dominio determina cuantos bytes se destinan para especificar el dominio, existiendo 4 variantes: 0 bytes, 1 byte, 3 bytes o 6 bytes. El campo direccin contiene la direccin del mensaje con el formato especificado en el formato de direccin.

2.1.5.5. Capa de transporte


La capa de transporte cumple la misin de asegurar la entrega confiable de paquetes de mensaje. Los tipos de envi que ofrece sta capa son: con confirmacin de recepcin, repetido sin confirmacin de recepcin y sin confirmacin de recepcin. Un envo con confirmacin de recepcin es aquel en donde el emisor del paquete de mensaje, una vez enviado ste ltimo permanece en espera hasta que responda el destinatario. El destinatario de un paquete puede ser un dispositivo o un grupo de ellos, se considera que el envo

FernandoArielBeunza79156

35

Tesis de Grado en Ingeniera Informtica fue satisfactorio cuando todos los destinatarios confirman la recepcin, salvo que se trate de un paquete broadcast en el cual el envo se considera satisfactorio cuando llega solamente una confirmacin de recepcin. El emisor puede reenviar el paquete varias veces hasta que reciba la confirmacin de recepcin o hasta que supere el lmite de cantidad de reenvos. Un envo repetido es similar al anterior, pero en ste caso, los paquetes se envan una cantidad determinada de veces sin esperar un confirmacin de recepcin. ste tipo de envo es menos confiable que el primero, pero recomendable en situaciones en donde el cantidad de miembros del grupo destinatario es mayor a la cantidad de reenvos utilizando el tipo de envo anterior. Por ltimo, existe el envo sin confirmacin, en el cual un paquete es enviado una sola vez si esperar la confirmacin de recepcin. ste tipo de envo es el menos confiable de todos, pero til cuando la informacin a enviar no es crtica. El paquete de transporte se compone de los siguientes campos: autenticacin, formato de paquete de transporte, nmero de transaccin y datos que transporta el paquete.

Figura 2.15. Estructura de paquete de transporte [Echelon99].

El campo de autenticacin es utilizado para indicar si el mensaje es autenticado o no. El formato de paquete de transporte define el formato del contenido transportado por el paquete, existiendo cinco tipos de formato: mensaje con confirmacin de recepcin, mensaje repetido, confirmacin de recepcin, resto de prembulo y resto de mensaje. Los dos primeros formatos de paquete son utilizados por la capa de presentacin para el envo de informacin. El tercer formato es empleado para confirmar la recepcin de mensaje y el contenido del paquete es el encabezado del mensaje recibido. Los ltimos dos formatos de paquete son utilizados para la confirmacin de recepcin de paquetes multicast.

2.1.5.6. Capa de sesin


La capa de sesin agrega control al intercambio de datos. Un dispositivo que necesita un servicio que brinda otro dispositivo, enva un pedido, y ste ltimo en respuesta a ese pedido enva una respuesta. ste mecanismo de pedido-respuesta puede ser implementado sobre todas las formas de comunicacin posible provista por las capas inferiores. El caso especial, es un pedido broadcast, en donde slo se tiene en cuenta la respuesta del primer dispositivo que responde. Tambin la presente capa define un protocolo de autenticacin, que permite a los dispositivos receptores, aceptar o rechazar mensajes segn el dispositivo emisor que los envi. sto es utilizado para prevenir el uso no autorizado a dispositivos y sus aplicaciones. La autenticacin de los mensajes se realiza por medio de una clave de 48 bits de longitud, y tanto el emisor como el receptor deben poseer la misma clave para que el mensaje sea aceptado. El paquete de sesin se conforma de los siguientes campos: autenticacin, formato de paquete de sesin, nmero de transaccin y datos que transporta el paquete.

36

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Figura 2.16. Estructura de paquete de sesin [Echelon99].

El campo de autenticacin es utilizado para indicar si el mensaje es autenticado o no. El formato de paquete de sesin define el formato del contenido transportado por el paquete, que puede ser: un pedido, una respuesta, un resto de prembulo o un resto de mensaje. Los dos primeros formatos se utilizan en transacciones en donde se involucran un origen y un destino, en cambio los dos segundos formatos son empleados en transacciones multicast.

2.1.5.7. Capa de presentacin


El objetivo de la capa de presentacin es agregar estructura a los datos que intercambian los dispositivos. Hasta esta capa, los datos enviados no se encontraban organizados dentro de ninguna estructura. La presente capa se encarga de definir un conjunto de tipos de datos que pueden ser simples (nmero enteros, punto flotante, etc.) o compuestos (estructuras conformadas a partir de tipos simples). Los datos organizados en las estructuras anteriores son designados variables de red, y un dispositivo puede tener mltiples variables de red. Una variable de red se caracteriza por tener: una direccin (lectura o escritura), un tipo (ver tabla 2.14) y una longitud.
Tipo de dato Bitfield Double Float Enumerated Float Reference Signed Character Signed Long Signed Quad Signed Short Unsigned Long Unsigned Quad Unsigned Short Punto flotante de 64 bits. Enumeracin de 8 bits con signo. Punto flotante de 32 bits. Referencia a un tipo de variable de red. Caracter de 8 bits con signo. Entero de 16 bits con signo. Rango -32768 a 32767 Entero de 32 bits con signo. Entero de 8 bits con signo. Rango -128 a 127. Entero de 16 bits sin signo. Rango 0 a 65536 Valor de 32 bits sin signo. Entero de 8 bits sin signo. Rango de 0 a 255. Descripcin Bit con o sin signo de 1 a 8 bits de longitud. Slo disponible dentro de una estructura o unin.

Unsigned Character Caracter de 8 bits sin signo.

Tabla 2.14. Tipos de datos definidos por la capa de presentacin [Echelon99].

Cada uno de los tipos anteriores puede combinarse para formar estructuras compuestas. Existen dos tipos de estructuras compuestas: estructuras y uniones. Una estructura se compone de cualquiera de los tipos descriptos en la tabla 2.14. En cambio, una unin puede contener una estructura o cualquier tipo de dato simple de la tabla 2.14.

FernandoArielBeunza79156

37

Tesis de Grado en Ingeniera Informtica Un paquete de capa de presentacin se encuentra compuesto de los siguientes campos: direccin, parte alta y baja del selector de variable de red, y contenido del paquete.

Figura 2.17. Estructura de paquete de presentacin [Echelon99].

El campo direccin es utilizado para indicar la direccin de la variables de red (entrada o salida). El selector de variable de red es el identificador de variable de red asociado a la variable contenida en el paquete de sesin.

2.1.5.8. Capa de aplicacin


La capa de aplicacin define un conjunto estndar de servicios de red para el intercambio de datos entre dispositivos de distintos fabricantes. A continuacin se describen los grupos en los cuales se clasifican los distintos servicios brindados por sta capa:

Configuracin de redes: provee un conjunto de comandos para configurar los parmetros de red de los dispositivos. Diagnstico de redes: provee un conjunto de comandos para que las herramientas de red puedan diagnosticar problemas en la red. Transferencia de archivos: soporta la transferencia de bloques de datos entre dispositivos y herramientas de red. Configuracin de aplicaciones: provee una interfaz estndar para configurar el comportamiento de los dispositivos. Especificacin de aplicaciones: provee un conjunto estndar de interfaces para documentar las tareas que realiza un dispositivo. Cada tarea se expone como un bloque funcional que se define como un conjunto de variables de red y propiedades de configuracin del bloque. Diagnstico de aplicaciones: provee una interfaz estndar para realizar pruebas sobre bloques funcionales y dispositivos. Administracin de aplicaciones: provee una interfaz estndar para activar, desactivar o modificar bloques funcionales de un dispositivo. Alarmas: provee una interfaz estndar que permite reportar advertencias. Registro de datos: provee una interfaz estndar para la recoleccin de datos de los dispositivos, que tambin pueden ser transferidos a otros dispositivos por medio de una interfaz estndar.

38

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Planificacin: provee una interfaz estndar para la planificacin de eventos basados en el tiempo. Administracin de fecha y hora: provee una interfaz estndar para sincronizar la fecha y hora de los dispositivos dentro de una red.

2.1.6. HomePlug
Homeplug es el nombre para una familia de especificaciones sobre la implementacin de redes de datos a travs del cableado elctrico existente en un hogar. La primera especificacin creada de sta familia fue denominada HomePlug 1.0, pensada para reemplazar a las redes de computadoras cableadas (par trenzado) e inalmbricas, aprovechando la red de electricidad existente en un hogar. Dicha especificacin evolucion en HomePlug AV, que ampli la velocidad de transferencia de la primera para permitir el transporte de audio, video y datos. De HomePlug AV, deriv HomePlug Green PHY, orientada al ahorro de energa y el aumento de la interoperabilidad.

2.1.6.1. HomePlug 1.0


HomePlug 1.0 fue especificado para el funcionamiento sobre las redes de alimentacin residencial. Define solamente dos capas de las propuestas por el modelo OSI: capa fsica y capa de control de acceso al medio MAC. Tambin especifica dos interfaces: la interfaz de cableado entre el dispositivo y la lnea de potencia (designado P1 en la figura 2.18), y la interfaz de uso de HomePlug con la que interactan los protocolos de capas superiores del modelo OSI (designado M1 en la figura 2.18).

Figura 2.18. Capas implementas [HomePlug1.0 ].

La capa fsica se compone de los bloques detallados en la figura 2.19. Recibe de la capa superior datos e informacin de control, ambos con diferentes codificaciones. El esquema de modulacin utilizado es OFDM, independientemente de la codificacin utilizada.

FernandoArielBeunza79156

39

Tesis de Grado en Ingeniera Informtica

Figura 2.19. Esquema del transceptor [HomePlug1.0 ].

La informacin de control es codificada aplicando un FEC implementado por un bloque codificador de producto seguido de un bloque intercalador, que convierten 25 bits del paquete de control original en cuatro smbolos OFDM de 84 bits por smbolo. En cambio los datos aplican otro FEC ms complejo compuesto fundamentalmente por un codificador Reed Solomon y un codificador convolucional, y el resultado final puede pasar por medio de un bloque intercalador o un bloque ROBO, segn el grado de redundancia requerido para enviar la informacin. Luego de codificar la informacin, segn el tipo que sea, es el tipo de modulacin que se aplica a cada portadora para transmitir dicha informacin, siendo que para la informacin de control se emplea modulacin BPSK, y para los datos pueden utilizarse DBPSK, DQPSK o ROBO. Del sistema de modulacin utilizado, depende la velocidad de transferencia alcanzada, cuyo rango oscila entre 1 y 14 Mbps. El smbolo OFDM utilizado se compone de 83 portadoras entre el rango de frecuencia de 4.5 a 20.7 MHz. Los dispositivos HomePlug 1.0 estn pensado para servir de puente entre las redes de informacin a travs de las lneas de potencia y otros tipos de redes de datos, como por ejemplo las redes Ethernet. La capa de control de acceso al medio se encarga de proveer a la capa superior (otras redes de datos) un mecanismo de transporte de datos por medio de las lneas de potencia de forma

40

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica confiable. Por ste motivo, la trama puede transportar entre 46 y 1500 bytes, ya que se adapta al tamao que pueden tener los paquetes Ethernet.

Figura 2.20. Estructura de trama de capa de control de acceso al medio [HomePlug1.0].

En la figura 2.20 se describe la composicin de una trama utilizada por la capa de control de acceso al medio, en donde se distinguen tres parte: un delimitador al comienzo, la trama propiamente dicha y un delimitador final. El delimitador de comienzo comienza con un prembulo, un indicador de comienzo de trama y 25 bits de informacin de control, en donde se indica entre otras cosas, el tamao de la trama. La trama comienza con un encabezado de la misma, en donde se encuentra informacin de control, direccin de origen y destino (48 bits cada una). Inmediatamente se encuentra el campo donde se transporta los datos provistos por la capa superior, seguido de un campo de relleno, y una suma de verificacin de 16 bits para deteccin de errores. Separado por un intervalo de tiempo, se encuentra el delimitador final compuesto por un prembulo e informacin de control. Como el canal de comunicacin que brinda las lneas de potencia es nico con varios dispositivos intentando hacer uso del mismo, es necesario la existencia de un mecanismo de control de acceso al medio. HomePlug 1.0 utiliza CSMA/CA con un esquema de prioridad para determinar que dispositivo tiene derecho a utilizar el canal en cada momento. Cuando varios dispositivos desean enviar una trama, primero se verifica la prioridad de cada uno de ellos, los que posean la prioridad ms alta entran al perodo de contencin, en donde de forma aleatoria se determina el quien gana el derecho de utilizar el canal de comunicacin. En la figura 2.21 se puede observar como transcurre en el tiempo el proceso anterior.

Figura 2.21. Control de acceso al medio [HomePlug1.0].

El perodo de resolucin de prioridad (PRS0 y PRS1), implementan un esquema de prioridad basado en cuatro niveles posibles. El perodo de Backoff es donde se desarrolla la contencin que termina resolviendo que dispositivo hace uso del canal de comunicacin. FernandoArielBeunza79156 41

Tesis de Grado en Ingeniera Informtica La capa de control de acceso al medio tambin implementa un esquema de fragmentacin y reensamblado para poder soportar el envo de paquetes de informacin, provenientes de la capa superior, cuya longitud supera la capacidad mxima que brinda la capa de control de acceso al medio. Un paquete puede transportar entre 210 y 1680 bytes, lo que permite encapsular un paquete Ethernet sin necesidad de fragmentacin. Los dispositivos se agrupan en redes lgicas, pudiendo existir varias de stas ltimas sobre una misma red elctrica. Cada red lgica tiene asociada una clave, utilizada por los dispositivos para el envo de paquetes, ya que stos se envan encriptados. Todos los dispositivos pertenecientes a una red lgica deben conocer la clave. Un dispositivo que quiera pertenecer a una red lgica debe conocer la clave, suministrada por el usuario del dispositivo, o por otro dispositivo que conozca la clave. Para la segunda alternativa, la clave es enviada por medio de un paquete encriptado con una clave que conocen los dos dispositivos involucrados.

2.1.6.2. HomePlug AV
HomePlug AV fue pensado para cubrir los requerimientos de las redes orientadas a entretenimiento (audio, video y datos) utilizando el cableado de electricidad existente en un hogar. Al mismo tiempo HomePlug AV brinda la posibilidad de coexistir con HomePlug 1.0 y servicios de BPL. La arquitectura de HomePlug AV (figura 2.22) se encuentra preparada para aceptar paquetes Ethernet por medio de la interfaz H1, lo que permite utilizar adaptar cualquier protocolo basado en IP a la tecnologa HomePlug AV. Existen dos planos diferentes dentro de la arquitectura: el plano de datos y el plano de control. El primer plano se conforma siguiendo el modelo tradicional de capas, capa de control de acceso al medio y capa fsica, con un capa de Convergencia por encima de la pila de protocolos. El segundo plano se conforma de un Administrador de Conexiones y un Coordinador Central, aunque l ltimo slo se encuentra activo en una de las estaciones de la red.

Figura 2.22. Arquitectura HomePlug AV [HomePlugAV].

La capa fsica trabaja sobre el rango de frecuencias comprendido entre los 2 y 28 MHz, empleando OFDM con 917 portadoras utilizables, combinado con un cdigo convolucional turbo TCC. Los mtodos de modulacin empleados para las portadoras varias desde BPSK hasta 1024 QAM . Todas estas caractersticas mencionadas logran una velocidad de transferencia de 200 Mbps. El transmisor se encuentra ligado a la capa de control de acceso al medio por tres entradas diferentes: HomePlug 1.0, HomePlug AV (control) y HomePlug AV (datos). La primera existe para garantizar la compatibilidad con el protocolo HomePlug 1.0. Las dos restantes responden a los dos 42 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica planos mencionados anteriormente, uno referidos a los datos y otro al control. En cambio, el receptor se encuentra diseado para recibir por un lado todo lo referente a HomePlug 1.0, y por el otro todo lo referente a HomePlug AV (datos y control) de forma conjunta. Los bloques que componen tanto el transmisor como el receptor se detallan en la figura 2.23.

Figura 2.23. Esquema del transmisor y receptor [HomePlugAV].

La capa de control de acceso al medio de HomePlug AV tiene la capacidad de brindar servicios orientados a la conexin libre de contencin, garantizando ancho de banda para aplicaciones de audio y video basado en el mecanismo de TDMA. Tambin ofrece servicios no orientados a la conexin con contencin y esquema de prioridad, para aplicaciones que slo requieran comunicaciones del tipo mejor esfuerzo, basado en el mecanismo CSMA/CA. Para proveer de forma eficiente los servicios anteriores, HomePlug AV implementa una arquitectura flexible centralmente administrada, por medio del Coordinador Central (figura 2.22). Dicho coordinador es el encargado de establecer el perodo de sealizacin y como se ubican temporalmente cada tipo de servicio provisto (figura 2.24).

FernandoArielBeunza79156

43

Tesis de Grado en Ingeniera Informtica

Figura 2.24. Distribucin temporal de cada tipo de servicio [HomePlugGP].

La figura anterior muestra como se compone el perodo de sealizacin, existiendo tres regiones: regin de sealizacin, regin CSMA y regin reservada. El perodo de sealizacin comienza un instante luego de la deteccin de cruce por cero de la seal de potencia, siendo durante la primer regin en donde el Coordinador Central transmite la organizacin del perodo de sealizacin. La siguiente regin se reserva para el trfico que utiliza contencin. Por ltimo, la regin reservada, es un perodo de tiempo libre de contencin donde se emplea TDMA. La capa de control de acceso tambin contiene un Administrador de Conexiones encargado de recibir las especificaciones de calidad de servicio requeridas de la capa superior a HomePlug AV, y en base a sto determinar que tipo de servicio de los provistos conviene utilizar (CSMA o TDMA). Tambin debe controlar si la calidad de servicio brindada corresponde a la solicitada, que en caso de no ser as, el Administrador de Conexiones debe aplicar las correcciones necesarias para cumplir con lo solicitado. La capa de Convergencia se encarga de encapsular los paquetes de datos provenientes de la capa superior a HomePlug AV, agregndoles un encabezado y una suma de verificacin, conformando un paquete MAC. ste ltimo paquete, para ser transmitido, es particionado en fragmentos de 512 bytes de longitud. Cada fragmento es encriptado y encapsulado dentro de un paquete de capa fsica, para luego ser enviado a su destino. En el receptor, se lleva a cabo los pasos inversos a los anteriores (desencriptacin y reeensamblaje), y el paquete recibido es despachado por la capa de Convergencia hacia la capa superior. Sobre la red elctrica de un hogar pueden existir varias redes lgicas conformadas por distintos dispositivos. Cada una de stas redes lgicas tiene asociado una clave utilizada para el encriptado de los paquetes que intercambian de forma segura los diferentes dispositivos de la red lgica. Otro elemento importante que poseen las redes lgicas es un Coordinador Central. Cada una de stas redes presenta un coordinador. La funcin de un Coordinador Central es administrar el ancho de banda de la red al cual pertenece, y controlar la admisin de nuevos dispositivos a la red lgica.

2.1.6.3. HomePlug Green PHY


Una red inteligente se define como la entrega de electricidad desde los proveedores hasta los consumidores utilizando dos vas de comunicacin digital para el control de los aparatos en los hogares de los consumidores, ahorro de energa, reducir costos y aumentar la fiabilidad y transparencia [HomePlugGP]. 44 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica Un sistema de comunicaciones confiable, que est presente en todas partes, es un elemento fundamental para la implementacin exitosa de una red inteligente. Debido a los diferentes requisitos existentes dentro de un hogar y la red de servicios pblicos, es necesario dividir las comunicaciones en dos partes: WAN (servicios pblicos de electricidad hacia el exterior) y HAN (electricidad hacia el interior). La implementacin de redes inteligentes hasta la fecha ha demostrado el gran potencial que tienen los usuarios de participar activamente en la conservacin de energa y reducir significativamente su el uso de electricidad en general.

Figura 2.25. Esquema de red inteligente [HomePlugGP].

Una de las diferencias ms importantes entre redes WAN y HAN, es que en las primeras las aplicaciones que hacen uso de la red tiene ms libertad para la adopcin de estndares, cosa que no ocurre en HAN, ya que la amplia gama de dispositivos que pueden estar presentes en un hogar requieren, para que puedan interoperar sin inconvenientes, la adopcin de estndares ampliamente aceptados por todos los fabricantes. Las especificaciones HomePlug Green PHY han sidos diseadas especficamente para soportar aplicaciones sobre redes del tipo HAN, sin afectar a otras aplicaciones existentes dentro del hogar. Dichas especificaciones derivan de HomePlug AV, lo que permite la interoperabilidad con el estndar IEEE P1901 [IEEEP1901]. La capa fsica de Home Plug Green PHY trabaja con un esquema de modulacin OFDM dentro del rango de frecuencias de 2 a 30 MHz. Las subportadoras empleadas son 1155, con una separacin entre subportadoras de 24,414 KHz, y moduladas utilizando QPSK. La velocidad mxima de transferencia que puede alcanzar es de 10 Mbps, implementando varios modos ROBO, pudiendo bajar dicha velocidad mxima a 5 Mbps y 4 Mbps ganando confiabilidad, con el agregado del mtodo FEC cdigo turbo . Comparado con Home Plug AV, las caractersticas anteriores parecen un retroceso (un solo esquema de modulacin de subportadora, velocidad de transferencia menor, implementacin de un slo mtodo FEC), pero viene de la mano de una reduccin de costos, de consumo de los dispositivos y de una mayor interoperabilidad. En cuanto a la capa de enlace de Home Plug Green PHY, resulta bsicamente en una simplificacin de la versin implementada en Home Plug AV, conservando el mismo mtodo CSMA y el mecanismo de prioridad, pero perdiendo en mecanismo opcional de TDMA.

FernandoArielBeunza79156

45

Tesis de Grado en Ingeniera Informtica

2.2. Redes en automviles


Los automviles hace tiempo requieren de redes para interconectar los diferentes dispositivos que los constituyen. El nmero de dispositivo va en aumento a medida que las regulaciones se hacen mas exigentes y los usuarios requieren cada da ms un mayor nivel de equipamiento. La utilizacin de cableado dedicado para cada dispositivo, en la actualidad, con el gran nmero de dispositivos presentes en un automvil, hace de sta una alternativa costosa. Se requiere de una forma de interconexin de los dispositivos que utilice una menor cantidad de cableado (por ejemplo topologa bus o anillo). Trabajar con un medio fsico compartido por varios dispositivos, vuelven ms complejas a las comunicaciones entre ellos. Pero sto ltimo, puede ser resuelto con la introduccin de microcontroladores cada vez ms poderosos y econmicos, haciendo que la ltima alternativa frente a la primera. Ya analizado el estado del arte de la tecnologa PLC, es necesario estudiar los estndares existentes en redes de automviles que no utilizan como medio fsico la tecnologa PLC, ya que algunas ideas que proponen pueden ser de utilidad para la integracin de ambas tecnologas.

2.2.1. CAN
El estndar CAN fue desarrollado por la empresa Robert Bosch GmbH a principios de la dcada de los 90, con el objeto de proveer un esquema de comunicaciones que soporte sistemas de control distribuido. ste estndar originalmente se encontraba orientado a la industria automotriz, pero con el tiempo tambin fue adoptado por la industria en general. Las especificaciones del estndar CAN se componen de dos partes conocidas como parte A y parte B. La parte A se encarga de definir el formato estndar de mensaje compatible con versiones anteriores. La parte B define el formato estndar y extendido de mensaje.

2.2.1.1. Modelo de capas


CAN adopta el modelo de capas como lo hacen otros estndares. Comparando CAN con el modelo de capas propuesto por OSI, CAN solamente define la capa fsica y la capa de enlace. La parte A (figura 2.26) define tres capas: fsica, transferencia y objeto; siendo stas dos ltimas equivalentes a la capa de enlace del modelo OSI. La parte B (figura 2.27) toma la misma organizacin que emplea OSI, y define las capas fsica y de enlace, sta ltima dividida en dos subcapas: control de acceso al medio (llamada MAC) y control de enlace lgico (llamada LLC).

46

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Figura 2.26. Modelo de capas propuesto por CAN A Figura 2.27. Modelo de capas propuesto por CAN B [Bosch91]. [Bosch91].

Respecto a la capa fsica, CAN no define especficamente el medio fsico utilizado como canal de comunicacin. De las diferentes variantes existentes, en el presente trabajo se tratar la que emplea cable par trenzado como canal de comunicacin, en donde las seales son codificadas utilizando tensin diferencial. La capa de enlace es la responsable del armado y desarmado de los mensajes, de la deteccin de errores, de controlar el acceso al medio (resolver el arbitraje), el filtrado de mensajes, entre otras funciones.

2.2.1.2. Capa fsica


La capa fsica de CAN se compone de tres subcapas (figura 2.48): sealizacin fsica, acoplamiento al medio fsico e interfaz dependiente del medio. El estndar slo define la subcapa de sealizacin fsica en donde se especifica la codificacin de los bits, la duracin de los mismos y el mecanismo de sincronizacin Las restantes subcapas son dependientes del medio fsico utilizado. En el presente trabajo se estudiar el medio definido por la norma ISO 11898-2.

FernandoArielBeunza79156

47

Tesis de Grado en Ingeniera Informtica

Figura 2.28. Subcapas que conforman la capa fsica de CAN [Zeltwanger].

Las redes CAN presentan topologa tipo bus, en donde la longitud del cable y la velocidad de transferencia se encuentran estrechamente relacionadas. La utilizacin de tensin diferencial sobre par trenzado le brinda mayor inmunidad al ruido electromagntico aumentando la confiabilidad. El bus requiere del agregado de dos resistencias de 120 ohms en los extremos del mismo para eliminar los reflejos de seal. Un bus CAN es capaz de soportar hasta 30 dispositivos. En la figura 2.29 se puede observar un ejemplo de como se constituye una red CAN.

Figura 2.29. Configuracin de una red CAN [StrangRckl].

Las velocidades de transferencia que soporta CAN estn comprendidas en el rango de los 10 Kbps a 1 Mbps. La velocidad est dada por el tiempo de duracin del bit empleado que sta en relacin a la longitud de bus. En la tabla 2.15 se puede observar la relacin que existe entre la velocidad de transferencia, la longitud del bus y el tiempo de duracin del bit.
Velocidad de transferencia 1 Mbps 800 Kbps 500 Kbps 250 Kbps 125 Kbps 62,5 Kbps 20 Kbps 10 Kbps Longitud del bus 30 metros 50 metros 100 metros 250 metros 500 metros 1000 metros 2500 metros Duracin del bit 1 microsegundo 1,25 microsegundos 2 microsegundos 4 microsegundos 8 microsegundos 20 microsegundos 50 microsegundos

5000 metros 100 microsegundos

Tabla 2.15. Relacin entre velocidad de transferencia, del longitud del bus y el tiempo de duracin del bit [Zeltwanger]

48

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica Segn la clasificacin de redes propuesta por SAE sobre la clasificacin de redes, se puede decir que los buses de longitud mayor a 500 metros entran dentro de la clase B (aplicaciones de propsito general), y los de longitud inferior a 500 metros entran dentro de la clase C (aplicaciones de control en tiempo real). La relacin entre velocidad y longitud muestra un cada exponencial (figura 2.30) a medida que crece la longitud del cable utilizado en el bus.

Figura 2.30. Velocidad de transferencia en funcin de la longitud del bus [Zeltwanger].

Los smbolos utilizados por CAN para codificar los valores de los bits permiten la existencia de un valor dominante sobre un recesivo. En ste caso particular el smbolo utilizado para el valor de bit cero corresponde al dominante, mientras que el valor uno corresponde al recesivo. ste esquema permite que en todo momento se pueda leer un estado vlido del bus (colisin no destructiva). sto es necesario, ya que CAN basa su sistema de resolucin de colisiones en la existencia de un estado dominante sobre uno recesivo, como se explicar ms en detalle cuando se hable sobre la capa de enlace.

2.2.1.3. Capa de enlace


Las funciones bsicas que cumple la capa de enlace implementada por CAN consisten en controlar el acceso al nico medio de comunicacin (el bus de datos), armar y desarmar tramas, y garantizar que los datos lleguen a su destino libre de errores. Una red CAN es una red multimaestro, es decir que no hay ningn dispositivo que tenga funciones especiales sobre el resto encargadas de la administracin de la red. Todos los dispositivos son capaces de hacer uso del bus para intercambiar informacin con otros dispositivos, siguiendo reglas sobre el uso del nico medio de comunicacin disponible (mecanismo de control de acceso al medio). El mecanismo de control de acceso al medio propuesto por CAN se basa en un sistema de prioridad mediante el cual se establece la urgencia de envo que presenta cada trama. sto se combina con el mtodo de acceso al medio CSMA/CR, que consiste en la deteccin y resolucin de las colisiones de tramas. El esquema propuesto por CAN, consiste en que los dispositivos que desean transmitir en un determinado instante, lo hagan, y mientras emiten los bits de la trama escuchen el canal de comunicacin. Como existe un estado dominante y uno recesivo, siempre los dispositivos detectarn un estado vlido en todo momento. En caso de que un dispositivo que se encuentre transmitiendo, detecte un estado del canal distinto al valor del bit emitido, ste cesa la transmisin, y comienza a recibir todos los bits que escucha del canal. sto ltimo se va repitiendo con el resto de los dispositivos que se encuentran transmitiendo en simultneo, hasta que solamente FernandoArielBeunza79156 49

Tesis de Grado en Ingeniera Informtica quede uno, quien es el ganador del arbitraje. Cuando el ganador del arbitraje termina de transmitir su trama, el resto de los dispositivos que perdieron la contienda, tienen una nueva trama recibida proveniente del ganador del arbitraje. Los perdedores del arbitraje deben repetir el intento de envo de sus respectivas tramas hasta que logren ganar el acceso al bus de datos. Para que ste esquema funcione, cada trama debe comenzar con una secuencia de bits que sea diferente en todas las tramas. sta secuencia constituye el campo de arbitraje de la trama, y con el esquema de bit dominante y recesivo, el dispositivo ganador del arbitraje siempre ser quien est enviando la trama de mayor prioridad (todos los bits con valor cero tienen la mxima prioridad y todos los bits con valor uno tiene la mnima prioridad).

Figura 2.31. Ejemplo de arbitraje [Zeltwanger].

En la figura 2.31 se puede observar un ejemplo de funcionamiento del mtodo de control de acceso al medio por prioridad. Como se puede ver existen tres dispositivos transmitiendo en simultneo. El primer dispositivo en abandonar la contienda es el nmero 2, ya que ste emite un bit de valor uno mientras que el resto emiten un bit de valor cero. Luego el siguiente en abandonar la contienda es el dispositivo 1, quedando solamente el dispositivo nmero 3 quien continua transmitiendo hasta el final de la trama. ste sistema no solamente resuelve las contienda en forma no destructiva, sino que tambin garantiza un tiempo determinstico para el envo de las tramas, ya que el tiempo que demora la transmisin de las tramas depende de la prioridad de los mismos. Una de las caractersticas particulares de CAN que la diferencia de otras redes, es que no existe el concepto de direccin de dispositivo. Lo nico que existe es el identificador de trama, que los dispositivos son capaces de filtrar, y de sta forma pueden determinar que tramas procesar. ste esquema de identificacin permite a CAN ser muy flexible en el agregado de nuevos dispositivos a la red, ya que no requiere de configuracin de los mismos. Adems el identificador de trama forma parte del campo de arbitraje de la trama, permitiendo que stas puedan ser asociadas a funciones, siendo algunas ms crticas que otras, pudiendo asignar mayor prioridad a las funciones crticas. Puede decirse tambin que cada identificador constituye una direccin de multicast debido a que el destinatario de una trama puede ser un dispositivo o un grupo de dispositivos, adems de existir una direccin de broadcast para el envo de tramas a todos los dispositivos del bus. La estructura de una trama utilizada por CAN para el envo de datos, bsicamente es similar tanto para la parte A como para la parte B. La diferencia existe en que la parte B implementa una estructura de mensaje extendido que permite utilizar identificadores de mensaje ms extensos. La estructura de mensaje propuesta por la parte A se puede observar en la figura 2.32, mientras que las estructuras definidas por la parte B pueden verse en la figura 2.33 (mensaje estndar) y la figura 2.34 (mensaje extendido).

50

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Figura 2.32. Estructura de trama estndar utilizada por CAN parte A [Reuss93].

Figura 2.33. Estructura de trama estndar utilizada por CAN parte B [Reuss93].

Figura 2.34. Estructura de trama extendida estndar utilizada por CAN parte B [Reuss93].

Una trama comienza con un bit de comienzo de trama (SOF) para indicar el comienzo de la misma, seguida de un identificador de 11 bits, seguido de un grupo de indicadores (varan segn la estructura de trama), y 4 bits que indican la cantidad de datos que transporta el mensaje (DLC). A continuacin se encuentran los datos que pueden ocupar de 0 a 8 bytes, segn lo especificado en el campo DLC. Luego de los datos se encuentra un cdigo de deteccin de errores CRC de 15 bits, un bit indicador de fin del cdigo CRC, 2 bits de ACKN utilizado por los receptores para indicar la correcta recepcin, y por ltimo 7 bits que indica el fin de la trama (EOF). El bit de RTR presente en todas las estructuras de tramas es utilizado para indicar si la trama es de datos (valor cero) o es una trama remota (valor uno). El bit de IDE solamente existen en las tramas de la parte B para indicar si en mensaje es estndar (valor cero) o extendido (valor uno). El bit SRR solamente se encuentra en la trama extendida de la parte B, y su finalidad debe a razones de compatibilidad con la trama estndar (reemplaza al bit RTR). Los bits destinados al identificador de trama y el bit RTR constituyen el campo de arbitraje utilizado para resolver colisiones. Adems de la trama utilizada para el envo de datos, existen otro tipo de tramas. La trama remota tiene una estructura similar a la de datos pero sin el campo de datos, y es enviada cuando un dispositivo requiere que le enven una trama de datos con el mismo identificador. Tambin existen otras tramas como la trama de error, enviada cuando un dispositivo detecta un error en el bus, y la trama de sobrecarga, enviada cuando un dispositivo se encuentra sobrecargado y necesita un tiempo adicional para terminar de procesar la ltima trama recibida. A cualquier tipo de trama, una vez armada, se le adiciona cada 5 bits consecutivos de igual valor uno de diferente valor (tcnica de bit stuffing). Luego se le aplica codificacin NRZ (Non Return to Zero), y finalmente se enva. Los dispositivos slo procesan tramas recibidas sin error. Cuando un dispositivo enva una trama, emite una secuencia de dos bits de valor uno en el campo ACKN de la trama. Cuando uno o varios de los dispositivos receptores detectan un error por medio del cdigo CRC, stos fuerzan una secuencia de bits 01 que colisionan con la secuencia original indicando la presencia de un error error de recepcin, forzando a los dems dispositivos receptores a no procesar la trama (aunque la recepcin haya sido correcta), y a que el emisor vuelva a reenviar la trama. El mecanismo de confirmacin de recepcin descripto permite que CAN brinde un servicio de comunicacin multicast

FernandoArielBeunza79156

51

Tesis de Grado en Ingeniera Informtica confiable (una trama es recibida de forma correcta por todos los receptores o por ninguno en caso de error). Los dispositivos tiene la capacidad de aislar fallas para no afectar el funcionamiento de la red entera. Cada dispositivo presenta un contador de errores, que cuando supera cierto lmite preestablecido, provoca la desconexin lgica del dispositivo (no recibe ninguna trama enviada ni interviene en la confirmacin de recepcin).

2.2.2. J1850
El estndar J1850 fue reconocido por SAE en el ao 1994, como una red para automviles clase B (segn clasificacin empleada por SAE). La idea de ste estndar es proponer una arquitectura abierta de bus de datos de topologa simple de bajo costo, que no necesitara de un dispositivo maestro para administrar el bus.

2.2.2.1. Modelo de capas


J1850 como otros estndares implementa una serie de capas que pueden ser comparadas con el modelo OSI. El objetivo de las capas es resolver los problemas relacionados con el proceso de comunicacin en diferentes niveles. En la figura 2.35 se puede observar el modelo de capas propuesto por J1850, en los cuales se implementan tres capas de las siete propuestas por el modelo OSI.

52

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Figura 2.35. Modelo de capas propuesto por J1850 [SAE94].

Como se puede observar en la figura anterior J1850 establece que la capa de aplicacin es la encargada de definir los tipos de mensajes, cdigos de diagnstico y parmetros; de sta forma todos los dispositivos interactan por medio de una interfaz nica permitiendo la interoperabilidad entre diferentes fabricantes de dispositivos. La capa de enlace se encarga de controlar el acceso al medio, resolviendo los conflictos que puedan existir cuando varios dispositivos intenten hacer uso del canal de comunicacin, y de permitir el flujo de datos libre de errores. La capa fsica es la encargada de codificar los datos empaquetados por la capa de enlace a travs de seales elctricas, existiendo dos variantes posibles, cada una con sus caractersticas fsicas particulares.

FernandoArielBeunza79156

53

Tesis de Grado en Ingeniera Informtica

2.2.2.2. Capa fsica


El estndar propone dos formas de codificar los datos en seales elctricas. La primer variante es la llamada VPW, que codifica los datos empleando ancho de pulso variable. La figuras 2.36 y 2.37 muestran los smbolos utilizados para codificar un bit de valor cero y un bit de valor uno, respectivamente. A su vez existen dos modos de codificacin, la denominada pasiva (a la izquierda de las figuras 2.36 y 2.37), y la denominada activa (a la derecha de las figuras 2.36 y 2.37). El modo pasivo viene dado por la forma de representar el smbolo utilizando el nivel bajo de tensin. El modo activo, al contrario del modo pasivo, emplea el nivel alto de tensin. En ambos modos, existe el concepto de bit dominante y recesivo, en el cual, ante una colisin de bits, el valor dominante prevalece sobre el valor recesivo. El valor del bit dominante es cero, mientras que el valor del bit recesivo es uno, independientemente del modo utilizado. Empleando stos smbolos, J1850 VPW puede transferir datos a una velocidad de 10,4 Kbps.

Figura 2.36. Codificacin de bit valor cero utilizado Figura 2.37. Codificacin de bit valor uno utilizado por J1850 VPW [SAE94]. por J1850 VPW [SAE94].

La otra variante llamada PWM, emplea modulacin de ancho de pulso para la codificacin de los datos. En la figura 2.38 se puede observar el smbolo utilizado para codificar un bit de valor cero, y en la figura 2.39 se puede observar el smbolo empleado para codificar un bit de valor uno. En J1850 PWM tambin existe el concepto de dominante y recesivo, en este caso un bit de valor cero es dominante frente a un bit de valor uno, ya que para el primero se emplea un pulso ms ancho que para el segundo. Gracias a stos smbolos, J1850 PWM puede transferir datos a una velocidad de 41,6 Kbps.

Figura 2.38. Codificacin de bit valor cero utilizado Figura 2.39. Codificacin de bit valor uno utilizado por J1850 PWM [SAE94]. por J1850 PWM [SAE94].

Los mecanismos de codificacin de bits anteriores tiene en comn el concepto de bit dominante y recesivo. sto es necesario para el mecanismo de resolucin de colisiones implementado por la capa de enlace. La topologa de red propuesta por J1850 consiste simplemente en una lnea a la cual se conectan todos los dispositivos del automvil. La longitud mxima que puede alcanzar la lnea es de 35 metros dentro del automvil, y 5 metros fuera de l, que se pueden combinar alcanzando los 40 metros en total. La cantidad mxima de dispositivos que pueden ser conectados a la lnea es 32, incluyendo tambin a los dispositivos que pueden encontrarse fuera del automvil. La lnea utilizada puede estar constituida por un solo cable (J1850 VPW) o por dos cables (J1850 PWM).

54

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

2.2.2.3. Capa de enlace


Una de las funciones que tiene la capa de enlace es controlar el acceso al canal de comunicacin. Al ser el bus de datos, el nico medio que poseen todos los dispositivos para transmitir informacin, es necesario establecer un protocolo que determine que dispositivo transmite cuando existen varios dispositivos queriendo hacer lo mismo. El protocolo propuesto por J1850 es similar al utilizado por CAN, se basa tambin en un esquema de prioridades para el envo de mensajes utilizando el concepto de bit dominante y recesivo, para resolver que dispositivo continua transmitiendo y que dispositivo cesa su transmisin. En las figuras 2.40 y 2.41 se pueden observar ejemplos de resolucin de colisiones para J1850 VPW y J1850 PWM.

Figura 2.40. Ejemplo de arbitraje J1850 VPW [SAE94].

Figura 2.41. Ejemplo de arbitraje J1850 PWM [SAE94].

El protocolo de resolucin de colisiones se basa en que los dispositivos pueden enviar bits y escuchar el canal en forma simultnea. Varios dispositivos pueden comenzar en un determinado momento a transmitir un mensaje. Cada mensaje tiene un encabezado constitudo por un campo de prioridad que especifica la prioridad del mensaje. Los bits de prioridad, como el resto de la informacin, es codificada empleando cualquiera de las variantes propuestas por J1850 (VPW o PWM). A medida que los dispositivos transmiten y detectan en el canal de comunicacin diferencias entre lo enviado y recibido, los dispositivos cesan sus transmisiones, hasta que uno ellos quede transmitiendo hasta el final del mensaje, porque que no detect diferencias. stas diferencias pueden ser detectadas gracias a que existe un valor de bit que es dominante sobre el otro, permitiendo en todo momento, que a pesar de la colisin de seales, siempre se pueda establecer el valor del bit. Un mensaje se encuentra compuesto por cinco partes: un indicador de comienzo de mensaje (llamado SOF), un encabezado, un campo de datos, un cdigo de deteccin de errores CRC y un FernandoArielBeunza79156 55

Tesis de Grado en Ingeniera Informtica indicador de fin de mensaje (llamado EOF). stas partes se disponen conforme lo muestra la figura 2.42.

Figura 2.42. Estructura de mensaje [Oliver].

Los indicadores de comienzo y fin de mensaje son delimitadores que avisan a los receptores cuando comienza y termina un mensaje. El encabezado de contiene informacin de control detallada en la figura 2.43.
Prioridad 3bits Tipode Modode Tipode IFR encabezado direccionamiento mensaje 1bit 1bit 1bit 2bits

Figura 2.43. Estructura de encabezado de mensaje.


Prioridad 3bits Tipode Modode Tipode Direccin Direccin IFR encabezado direccionamiento mensaje deorigen dedestino 1bit 1bit 1bit 2bits 8bits 8bits

Figura 2.44. Estructura de encabezado extendido de mensaje.

La prioridad especifica la prioridad que presenta el mensaje y se utiliza para la resolucin de colisiones. El tipo de encabezado indica si el mensaje emplea el encabezado comn (figura 2.43) o el extendido (figura 2.44). El encabezado extendido tiene una longitud de 3 bytes, el primer byte corresponde al encabezado comn y el resto de los bytes se destina a la direccin del dispositivo que dio origen al mensaje y a la direccin a quien se destina el mensaje. El campo IFR indica si el mensaje requiere de una respuesta o no. El modo de direccionamiento indica si el mensaje especifica como destino una direccin fsica o una direccin funcional. El tipo de mensaje especifica el tipo de mensaje enviado que se encuentra relacionado con el IFR y el modo de direccionamiento. La longitud mxima que puede tener un mensaje, incluyendo informacin de control, es de 12 bytes. Existen dos tipos de direcciones que se pueden especificar en los mensajes: las fsicas y las funcionales. Las direcciones fsica identifican a dispositivos en particular y son nicas, no hay dos dispositivos con la misma direccin. Son utilizadas cuando un dispositivo quiere enviar un mensaje a otro en particular. Las direcciones funcionales identifican a una funcin que puede ser ejecutada por varios dispositivos, lo que implica que un mensaje con este tipo de direccin puede tener varios destinatarios. Cada dispositivo tiene definido un conjunto de funciones, y a partir de ste conjunto la capa de aplicacin decide que mensaje es aceptado.

2.2.2.4. Capa de aplicacin


La capa de aplicacin implementa una interfaz que permite la transferencia de informacin de uno dispositivo a otros. Los dispositivos intercambian informacin por medio de mensajes. Existen dos grupos de mensajes: los mensajes en modo normal de operacin definidos en el estndar SAE J2178 y los mensajes de diagnstico definidos en los estndares SAE J1979 y SAE 56 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica J2190. Tambin sta capa implementa una serie de cdigos de falla asociados a un conjunto de averas definidas en el estndar SAE J2012. Otra funcin que brinda est capa es la de filtrado de mensajes. Debido a que los mensajes enviados por medio del bus de datos son recibidos en todos los dispositivos, pueden que stos no estn interesados en todos los mensajes. Para evitar la sobrecarga de trabajo de los dispositivos, se dispone de un mecanismo de filtrado que permita discriminar los mensajes por medio de un identificador.

2.2.3. OSEK/VDX
El proyecto OSEK fue iniciado en el ao 1993 por un conjunto de empresas pertenecientes a la industria del automvil alemana. El objetivo principal del proyecto es proponer una arquitectura de control distribuido dentro de los automviles que sea abierta, para que diversos fabricantes puedan desarrollar dispositivos que sean interoperables entre s. Las empresas francesas PSA y Renault tambin se encontraban trabajando en un proyecto similar llamado VDX, y se fusionaron al proyecto OSEK en el ao 1994, conformando un nico estndar llamado OSEK/VDX.

2.2.3.1. Arquitectura
El estndar OSEK/VDX define un conjunto de interfaces que permiten el desarrollo de componentes de software porttiles y reutilizables. La idea del estndar es abstraer la aplicacin del hardware utilizado en los dispositivos interconectados a travs de una red. Una aplicacin interacta con la interfaz, lo que permite el desarrollo del estndar para diversas plataformas y la evolucin del mismo, sin necesidad de modificar la aplicacin. En la figura 2.45 se puede observar la arquitectura propuesta por el estndar.

Figura 2.45. Arquitectura de OSEK/VDX [LeenHeffernanDunne].

FernandoArielBeunza79156

57

Tesis de Grado en Ingeniera Informtica Si se compara el modelo OSI con la arquitectura de OSEK/VDX, se puede observar que OSEK/VDX implementa las capa de enlace y de red. La aplicacin interacta por medio de la interfaz de comunicacin y la interfaz de red, con la capa de interaccin y el Administrador de Red, respectivamente. La capa de interaccin se encuentra al tope de la pila de capas constituidas por la capa de red y de enlace. El Administrador de Red interacta con la capa de interaccin y con la capa de enlace. Finalmente la capa de enlace interacta con el medio fsico de conexin por medio del hardware de comunicacin (capa fsica del modelo OSI).

2.2.3.2. Implementacin
OSEK/VDX implementa un entorno de trabajo distribuido dentro de un vehculo, basndose en los mismos principios utilizados para implementar entornos distribuidos que operan dentro de las redes de datos de gran tamao. De ste modo se pretende reducir costos en la creacin de software reutilizable. Pero la flexibilidad de OSEK/VDX requiere de memorias ROM y RAM adicionales, adems de sobrecargar a los procesadores. La clave del xito de ste modelo depende que los costos adicionales de hardware sean absorbidos por el ahorro asociado por la implementacin de software reutilizable.

Figura 2.46. Indepedencia de OSEK/VDX [LeenHeffernanDunne].

Tambin OSEK/VDX puede ser visto como un sistema operativo desarrollado para diversas plataformas de procesador, soportar diversas interfaces de comunicacin y servir a mltiples aplicaciones. Como todo sistema operativo, OSEK/VDX debe administrar las diferentes tareas que se encuentren en ejecucin, procesar las diferentes solicitudes de interrupcin, proveer mecanismos de comunicacin entre procesos en ejecucin y brindar tratamiento a los errores que ocurran. El estndar por s mismo no especifica como se llevan a cabo las comunicaciones entre dispositivos, como lo hacen otros estndares, sino que define un esquema multiplataforma que puede complementarse con distintos estndares de comunicacin existentes como CAN y J1850.

2.2.4. LIN
Las redes LIN fueron pensadas para ser redes de bajo costo, como complemento de otras redes presentes en un automvil. La idea surge del principio que dentro de un automvil se disponen de una gran cantidad de dispositivos, siendo algunos de baja complejidad (como por 58 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica ejemplo, una tecla de levantavidrios); e interconectar este tipo de dispositivos por medio de una red como CAN o J1850, los haran ms complejos y costosos. Adems stos dispositivos tienden a agruparse en determinados sectores de un automvil (la tecla de levantavidrios se encuentra en la puerta muy prxima del motor que ejecuta la accin de subir y bajar el vidrio). Entonces la propuesta de LIN es crear una red de bajo costo y simple que permita interconectar dispositivos muy prximos entre s, y que tambin permita las comunicaciones con dispositivos distantes empleando pasarelas conectadas a una red de cobertura ms amplia como CAN o J1850 (con la tecla de levantavidrios de una puerta controlar la ventanilla de otra puerta).

2.2.4.1. Capa fsica


La capa fsica de LIN especifica como debe ser el medio fsico de comunicacin, la interfaz elctrica que debe implementar un dispositivo para poder conectarse, los valores de tensin utilizados para codificar los bits de informacin, y las velocidades de transferencia permitidas. Un bus LIN se encuentra constituido por un nico cable, conformando una red de topologa lineal. El bus puede tener una longitud mxima de 40 metros, y puede soportar hasta 16 dispositivos conectados. Sobre ste bus, los diferentes dispositivos conectados, pueden transmitir y recibir, empleando una interfaz cuyo esquema bsico puede observarse en la figura 2.47, en donde la lnea K corresponde al bus de datos que es alimentado por la tensin de la batera. El transistor es el componente que permite al dispositivo cambiar el estado del bus en funcin de la informacin que desee transmitir. El dispositivo recibe informacin leyendo el estado del bus en el punto que se encuentra entre la resistencia y el transistor.

Figura 2.47. Esquema de interfaz fsica [Wense00].

Los niveles de tensin empleados para codificar los bits de datos se encuentran definidos en relacin a la tensin de la batera. La figura 2.48 muestra el rango de tensiones utilizado para el nivel alto y el bajo. El nivel bajo resulta ser dominante frente al alto debido a la configuracin de la interfaz de la figura 2.47, en un transistor tiene la capacidad de forzar a todo el bus a un estado bajo sin importar el estado que tengan las interfaces de los otros dispositivos conectados al bus.

Figura 2.48. Rango de tensiones para niveles alto y bajo sobre la lnea de transmisin [Wense00].

Figura 2.49. Umbrales para niveles alto y bajo soportados por los receptores [Wense00].

FernandoArielBeunza79156

59

Tesis de Grado en Ingeniera Informtica En la figura 2.49 se puede observar los umbrales que deben soportar los receptores para poder detectar los distintos niveles del bus. Como es de esperar los rangos comprendidos son ms amplios que los vistos en la figura 2.48, por cuestiones de compatibilidad. El ancho de pulso que puede tener cada smbolo utilizado para codificar un bit de datos depende de la velocidad de transferencia que se utilice. LIN soporta una velocidad de transferencia mxima de 20 Kbps, lo que se traduce en un ancho de pulso de 50 microsegundos, aunque en la industria automotriz suele trabajarse con velocidades de 2,4 Kbps; 9,6 Kbps y 19,2 Kbps [Rey03].

2.2.4.2. Capa de enlace


La simpleza de LIN radica en que el mecanismo de acceso al medio fsico no consiste en algoritmos complejos, ya que el esquema de una red consiste en un dispositivo maestro que administra el uso del medio de comunicacin, y en dispositivos esclavos que siguen las instrucciones del dispositivo maestro. El beneficio de la simpleza debe pagarse teniendo concentrada las funciones vitales de la red en un slo dispositivo, que en caso de falla de ste, la red queda paralizada. El intercambio de datos entre los diferentes dispositivos de una red LIN se realiza por medio de tramas conformadas por los campos detallados en la figura 2.50.

Figura 2.50. Estructura de una trama [LIN10].

Una trama se compone de un encabezado y una respuesta. El encabezado siempre es generado por el dispositivo maestro, y consiste en un espacio inicial utilizado para marcar el inicio de una trama, seguido de una secuencia alternada de bits de valor cero y uno para sincronizar los dispositivos esclavos con el maestro, y finalmente un identificador protegido. ste identificador se conforma de los campos detallados en la figura 2.51.

Figura 2.51. Estructura del campo identificador [LIN10].

El campo identificador comienza con un bit de comienzo, seguido de 6 bits correspondientes al identificador, 2 bits de paridad que protegen el identificador anterior ante errores de transmisin, y finalmente un bit de final de campo. El dispositivo esclavo que reconozca el identificador transmitir la respuesta a continuacin del encabezado de la trama. Dicha respuesta puede contener hasta 8 bytes estructurados de la forma descripta en la figura 2.52.

60

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Figura 2.52. Estructura de un campo de dato [LIN10].

Luego de la secuencia de bytes de datos, el dispositivo esclavo emite una suma de verificacin, para que el dispositivo maestro pueda verificar si los datos recibidos contienen errores o no. En la figura 2.53 se describe un ejemplo de secuencia de envo de encabezado y recepcin de datos.

Figura 2.53. Transmisin de una trama [Wense00].

Los identificadores se encuentran clasificados segn los datos de la trama: los identificadores comprendidos entre 0 y 59 se emplean para el transporte de seales, los comprendidos entre 60 y 61 se utilizan para transportar datos de diagnstico y configuracin, y los comprendidos entre 62 y 63 se encuentran reservados para aplicaciones futuras. Existen diferentes tipos de tramas: incondicionales, activadas por evento, de diagnstico y reservadas. Las tramas incondicionales transportan seales y presentan identificadores comprendidos entre 0 y 59. ste tipo de tramas permiten a los dispositivos esclavos enviar datos a otros dispositivos. El dispositivo maestro es quien siempre inicia la trama enviando el encabezado, y luego el dispositivo esclavo correspondiente enva los datos solicitados que son recibidos por los dispositivos destinatarios. Las tramas activadas por eventos son enviadas por el dispositivo maestro destinadas a uno o varios dispositivos esclavos. Si los dispositivos esclavos tiene asociado a una trama activada por evento una trama incondicional (est ltima es enviada luego de recibirse la primera). sto ltimo puede dar lugar a colisiones de tramas. El mecanismo de deteccin de colisin se basa en la existencia de bits de valor dominante y recesivo que permiten a los dispositivos detectar cuando una transmisin est siendo interferida por otra. El dispositivo maestro es el encargado de la resolucin de la colisin, por medio de una tabla predefinida especialmente para esta situacin, que le indica a cada dispositivo esclavo en que momento emitir su respuesta. Las tramas de diagnstico utilizan los identificadores 60 y 61, y son utilizadas para funciones de diagnstico y configuracin de los dispositivos de la red. Por ltimo las tramas reservadas emplean identificadores 62 y 63, y no tienen una funcin especfica ya que se reservan para aplicaciones futuras.

2.2.5. D2B
ste bus fue desarrollado por la empresa Phillips en los comienzos de la dcada del 80. Su finalidad era poder interconectar diferentes dispositivos domsticos de audio y video. La empresa FernandoArielBeunza79156 61

Tesis de Grado en Ingeniera Informtica Mercedes Benz adopt D2B para interconectar los dispositivos de audio y video (radio, cargador de CD, etc.) de sus automviles.

2.2.5.1. Medio fsico


D2B fue pensado para utilizar par trenzado o fibra ptica. Como en sta parte del presente trabajo, se analizan las redes utilizadas en automviles, solamente se hablar de la implementacin de ste bus sobre fibra ptica, ya que es el medio fsico empleado por la empresa Mercedes Benz para la construccin de sus automviles. La implementacin de D2B propuesta por Mercedes Benz consiste en una red integrada por fibra ptica y cableado elctrico. La fibra ptica es utilizada para el envo de informacin y los dispositivos se interconectan formando una red de topologa tipo anillo. El cableado elctrico es utilizado para el envo de la seal de activacin de los transceptores de fibra ptica de cada uno de los dispositivos, y emplea una topologa de red tipo estrella. La figura 2.54 muestra las diferentes topologas adoptadas por la fibra ptica y el cableado elctrico de la red.

Figura 2.54. Configuracin de D2B implementada por Mercedes Benz [D2B04].

Una red D2B puede soportar hasta 6 dispositivos conectados, siendo uno de ellos el maestro, y el resto esclavos. La fibra ptima permite que la velocidad de transferencia alcance los 5,65 Mbps, debido a la inmunidad al ruido electromagntico que ste medio posee. El largo mximo que puede alcanzar el cable de fibra ptica varia segn la cantidad de acopladores: si no se emplean acopladores el cable puede tener hasta un largo de 10 metros, si se introduce un acoplador el largo se reduce a 7 metros, y si se introducen dos acopladores el largo no puede alcanzar los 3,6 metros [D2B02]. Adems el cable debe tener un radio de curvatura mnimo de 25 milmetros para que no se dae. Los beneficios de D2B vienen dados fundamentalmente por las ventajas de que brinda la fibra ptica (altas velocidades de transferencia e inmunidad al ruido electromagntico), pero tambin se hacen evidentes las desventajas de sta: las distancias no son extensas (y disminuyen con el uso de acopladores), los cables son frgiles (y su curvatura se encuentra limitada), y en caso de rotura la reparacin es costosa.

62

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

2.2.5.2. Control de acceso al medio


Una red D2B se compone de un dispositivo maestro, y varios dispositivos esclavos (hasta 5). Los dispositivos conforman un anillo por medio de los cables de fibra ptica, y de sta forma un paquete transmitido por el dispositivo maestro pasa por todos los dispositivos esclavos para ser recibido por el dispositivo maestro. El dispositivo maestro puede ser una radio o un tablero de comandos, mientras que los dispositivos esclavos pueden ser cargadores de CD, dispositivos de control de voz, telfonos, etc. El dispositivo maestro es responsable de almacenar la configuracin del anillo, generar la seal elctrica para la activacin de los transceptores de los dispositivos de la red (ya que stos se desactivan cuando no se enva informacin para ahorrar energa), inicializar el anillo, mantener el anillo, desactivar el anillo, detectar errores de funcionamiento del anillo y ser una pasarela entre la red D2B y la red CAN (red utilizada por otros dispositivos del automvil). La secuencia de inicializacin del anillo comienza cuando el dispositivo maestro emite un pulso de 80 milisegundos por medio del cableado elctrico, para que el resto de los dispositivos esclavos activen sus transceptores. Cuando se activan todos los transceptores, ya se encuentra disponible el canal ptico, para que el dispositivo maestro enve un pulso por medio de ste canal. El pulso recorre todo el anillo, siendo recibido y reenviado por todos los dispositivos esclavos, hasta que el dispositivo maestro recibe el pulso que emiti. En ste momento, el dispositivo maestro reconoce que se constituy el anillo, entonces enva otro pulso que recorre todo el anillo nuevamente para indicar a cada dispositivo esclavo que el anillo est listo para la circulacin de informacin a travs de l. Una vez constituido el anillo, la informacin fluye a travs de el por medio de paquetes que contiene cierta informacin de control que permite determinar el destinatario de los mismos. Todos los paquetes fluyen por el anillo, pero slo procesa el paquete el dispositivo cuya direccin coincide con el destinatario indicado en el paquete. Cuando no hay necesidad de transmitir informacin, el dispositivo maestro indica la desactivacin de los transceptores de todos los dispositivos de la red.

2.2.5.3. Estructura de paquete


La estructura de paquete empleada por D2B para el transporte de informacin a travs del anillo se encuentra conformado por un bit de comienzo, la direccin del dispositivo maestro, la direccin del dispositivo esclavo, informacin de control y la informacin a enviar. En la figura 2.55 se puede observar la estructura del paquete.

Figura 2.55. Estructura de paquete utilizado por D2B [Paret05].

FernandoArielBeunza79156

63

Tesis de Grado en Ingeniera Informtica En un paquete enviado por el dispositivo maestro a un dispositivo esclavo, la direccin del primero constituye la direccin de origen y la del segunda la direccin de destino. Las direcciones son codificadas utilizando 12 bits.

2.2.6. MOST
MOST constituye una evolucin de D2B desarrollada por las empresas BMW, DaimlerChrysler, Harman/Becker y Oasis. A diferencia de D2B, el uso de ste bus no es exclusivo de Mercedes Benz, que tambin ha adoptado MOST en reemplazo de D2B. Las mejoras incluyen velocidad de transferencia, cableado, cantidad de dispositivos soportados, entre otras.

2.2.6.1. Modelo de dispositivo


Un dispositivo MOST consiste en una unidad fsica que se conecta a una red MOST por medio de una interfaz fsica. Dentro de un dispositivo pueden existir varias aplicaciones que interactan con los servicios de red. Los servicios de red son los que tiene acceso directo a la interfaz de red MOST. La interfaz de red es la encargada de enviar las tramas generadas por los servicios de red independientemente del medio fsico de comunicacin utilizado. En la figura 2.56 se detallan cada uno de los componentes mencionados anteriormente.

Figura 2.56. Modelo de dispositivo MOST [MOST10].

MOST fue diseado para que sea independiente del medio fsico utilizado como canal de comunicaciones. Puede trabajar sobre cableado elctrico (par trenzado) o fibra ptica. En este trabajo slo se hablar de fibra ptica, ya que es el medio fsico ms conocido en la industria del automvil.

2.2.6.2. Capa fsica


La capa fsica de MOST tiene varias cosas en comn, comparada con la de D2B. Igual que sta ltima, los dispositivo se encuentran conectados por medio de fibra ptica y cableado elctrico. 64 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica La red de fibra ptica adopta una topologa anillo y es empleada para el transporte de datos. En cambio, la red elctrica presenta una topologa estrella y su funcin es la de transporta la seal de activacin de los transceptores de los dispositivos conectados a la red MOST. En la figura 2.57 se puede observar un ejemplo de como se conforma una red MOST.

Figura 2.57. Ejemplo de configuracin anillo de MOST [MOST04].

A diferencia de D2B, MOST introduce algunas mejoras con el objetivo de mejorar las prestaciones. La primer mejora consta en el cableado ptico, que al utilizar fibra ptica plstica, permite aumentar la longitud mxima permitida (21 metros sin acopladores y 3,962 metros con tres acopladores), y no tiene el inconveniente del radio de curvatura mnimo que presenta D2B. Adems la velocidad de transferencia se eleva a 24,8 Mbps y la cantidad mxima de dispositivos soportados por la red asciende a 64. Respecto a la parte elctrica, introduce mejoras en cuanto al sistema de activacin de los dispositivos, en lugar de que el dispositivo maestro sea el encargado de proveer la alimentacin de ste sistema, en MOST todos los dispositivos se encargan de ello.

2.2.6.3. Capa de red


Una red MOST se conforma de un dispositivo maestro, y varios dispositivos esclavos, como en D2B. El dispositivo maestro es el encargado de almacenar la configuracin del anillo, generar la seal elctrica para la activacin de los transceptores de los dispositivos de la red, inicializar el anillo, mantener el anillo, desactivar el anillo, detectar errores de funcionamiento del anillo, ser pasarela entre MOST y otra red (como CAN), y ser la pasarela de diagnstico para los dispositivos esclavos. En la figura 2.57 se puede ver que el dispositivo maestro encargado de las funciones anteriores es el Audio Gateway. Un dispositivo esclavo debe encargarse de monitorear la presencia de la seal de activacin de los transceptores, generar la seal de activacin ante un requerimiento de ste, mantener el anillo una vez iniciado por el dispositivo maestro, detectar errores de funcionamiento del anillo, y responder a la informacin de diagnstico requerida por el dispositivo maestro. La secuencia de inicializacin del anillo es similar a la empleada por D2B, con la diferencia de que en MOST cualquier dispositivo puede emitir la seal de activacin de los transceptores que desencadena el proceso de inicializacin del anillo. Cuando se encuentran activados todos los transceptores, el dispositivo maestro enva un pulso por medio de ste canal. El pulso recorre todo el anillo, siendo recibido y reenviado por todos los dispositivos esclavos, hasta que el dispositivo FernandoArielBeunza79156 65

Tesis de Grado en Ingeniera Informtica maestro recibe el pulso. En ste momento, el dispositivo maestro reconoce que se encuentra constituido el anillo, entonces enva otro pulso que recorre todo el anillo nuevamente para indicar a cada dispositivo esclavo que el anillo est listo para la circulacin de informacin a travs de l. En un anillo constituido, la informacin fluye a travs de l de diversas formas, dependiendo de la naturaleza de los datos. Cuando no hay necesidad de transmitir informacin, el dispositivo maestro indica la desactivacin de los transceptores de todos los dispositivos de la red. Segn la naturaleza de los datos provenientes de la capa de aplicacin, la capa de red provee una serie de mecanismos de transporte para cada tipo de datos. Dichos mecanismos pueden observarse en la clasificacin detallada en la figura 2.58.

Figura 2.58. Mecanismos de transporte de datos [MOST10].

Los mensajes enviados por medio del canal de control son cortos y transfieren informacin de control requerida por las aplicaciones. Los destinatarios de este tipo de mensajes pueden ser un dispositivo (unicast), un grupo de ellos (multicast) o todos (broadcast). Cuando se enva este tipo de mensajes, el arbitraje del medio es realizado por el controlador de interfaz de red MOST, garantizando que el acceso al medio sea independiente de la carga de la red. ste tipo de mensajes pueden ser retransmitidos, en caso de error, la cantidad de veces indicada por la aplicacin que los genera. Todo tipo de datos no que no son transmitidos por medio del canal de control, pueden ser paquetes de datos o flujo de datos. Los paquetes de datos son empleados para el envo de rfagas de datos. La cantidad de datos enviados por medio de paquetes es mayor a los enviados por medio del canal de control. Los paquetes pueden estructurarse de dos formas segn el tipo de direccin utilizada, como puede verse en las figuras 2.59 y 2.60.
Encabezado 12 bytes Direccin Direccin de destino de origen 2 bytes 2 bytes CRC Datos

4 bytes 6 a 1524 bytes

Figura 2.59. Estructura de paquete para direcciones de 16 bits [MOST10].

66

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Encabezado 12 bytes

Direccin Direccin de destino de origen 6 bytes 6 bytes

CRC

Datos

4 bytes 0 a 1506 bytes

Figura 2.60. Estructura de paquete para direcciones de 48 bits [MOST10].

Ambas estructuras son bsicamente similares en cuanto al encabezado, cdigo detector de errores CRC, y el campo de datos (su longitud mxima vara segn el tipo de direcciones utilizados). Las direcciones pueden ser de 16 bits (direcciones MOST) o de 48 bits (direcciones MAC). El mtodo de acceso al medio utilizado para el envo de paquetes de datos es por medio de la circulacin de testigo por el anillo de la red. Los flujos de datos pueden ser de naturaleza sincrnica o iscrona. Los flujos del primer tipo se refieren a datos en tiempo real como audio, video o datos originados por sensores. El mtodo de acceso al medio utilizado en este caso es multiplexado por divisin de tiempo TDM. Los flujos del primer tipo son similares a los del primero, con la diferencia de que su muestreo no se realiza con el reloj del sistema. El mtodo de acceso al medio empleado es el mismo que para los flujos sincrnicos.

2.2.6.4. Capa de aplicacin


La capa de aplicacin consisten en un conjunto de definiciones sobre el formato y el significado de los datos intercambiada entre las capas de aplicacin de los distintos dispositivos. Los mensajes a nivel de capa de aplicacin son independientes de los aspectos fsicos de la red, de sta manera las comunicaciones entre aplicaciones se realizan sobre canales virtuales. En la figura 2.61 se puede observar las comunicaciones virtuales asociadas a las comunicaciones reales llevadas a cabo por los servicios de red y los controladores de interfaz de red MOST.

Figura 2.61. Comunicacin virtual entre dos dispositivos a nivel de capa de aplicacin [MOST10].

Todos los mensajes de la aplicacin son finalmente transferidos a travs del canal de control o el canal de paquetes de datos provistos por la red MOST. Dependiendo de la cantidad de datos que se requiere enviar, se puede emplear un mensaje de transferencia nica (telegrama), o de lo contrario por medio de transferencia segmentada.

FernandoArielBeunza79156

67

Tesis de Grado en Ingeniera Informtica La estructura de mensaje para una transferencia nica, o telegrama (figura 2.62) se compone de la direccin de origen del mensaje, la direccin destinataria del mismo, un identificador de mensaje, un identificador de telegrama, la cantidad de datos transportada y los datos transportados.

Figura 2.62. Estructura de mensaje utilizado para transferencia simple [MOST10].

El tamao de las direcciones del mensaje son 16 bits. Para la identificacin de los mensajes se destinan 32 bits, mientras que para identificar el telegrama se emplean 4 bits. Los 12 bits destinados a almacenar la cantidad de datos transportada. Una transferencia simple puede transporta hasta 45 bytes. La estructura de mensaje empleada para transferencias segmentadas es similar a la empleada para los mensajes de transferencia nica. Se diferencian en que los mensajes para transferencias segmentadas necesitan de un contador de mensaje (ver figura 2.63).

Figura 2.63. Estructura de mensaje utilizado para transferencia segmentada [MOST10].

La estructura de encabezado no se modifica, salvo el agregado de contador de mensaje de 8 bits de longitud que le resta un byte a la capacidad de transporte de datos. En total, la transferencia segmentada tiene la capacidad de transportar hasta 65535 bytes, distribuidos en mltiples segmentos.

2.2.7. FlexRay
El estndar FlexRay fue desarrollado por el consorcio del mismo nombre, integrado por un conjunto de empresas fabricantes de automviles y de electrnica, entre los aos 2000 y 2009, para superar en prestaciones a buses como CAN y MOST.

2.2.7.1. Capa fsica


Una de las caractersticas que poseen los dispositivos que cumplen con el estndar FlexRay, frente a otros dispositivos que emplean otros estndares, es la capacidad de poder utilizar dos medios fsicos de comunicacin en forma paralela. sto posibilita aumentar la confiabilidad del bus de datos y poder utilizar diversas topologas de red para interconectar los dispositivos. El medio fsico empleado para implementar cada canal de comunicacin es par trenzado sin blindaje. La utilizacin de seales diferenciales para transmitir la informacin permite el ahorro de 68 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica utilizar cable blindaje. sto combinado con el hecho de que cada dispositivo puede trabajar con dos canales en simultneo a velocidades de transferencia de hasta 10 Mbps, hace que FlexRay sea muy competitivo frente a soluciones costosas como D2B o MOST que emplean cableado de fibra ptica. La arquitectura de un dispositivo que cumple con el estndar FlexRay se compone bsicamente de las siguientes partes (figura 2.64): un microcontrolador (propio de cada dispositivo), un Controlador de Comunicaciones (que implementa FlexRay), dos transceptores (uno para cada canal de comunicacin), y una fuente de alimentacin (que suministra energa a todas las partes anteriores).

Figura 2.64. Arquitectura del hardware de un dispositivo FlexRay [FlexRay].

Las topologas de red que se permite implementar FlexRay son variadas gracias a la disposicin de dos canales de comunicacin paralelos. La topologa ms simple que se puede utilizar es la lineal, en donde los dispositivos de la red puede conectarse a uno de los canales o a los dos, como se muestra en la figura 2.65.

Figura 2.65. Topologa lineal pasiva [FlexRay].

Dependiendo de la funcionalidad de cada dispositivo, podr requerir de uno o dos canales de comunicacin, siendo recomendado para funciones crticas el empleo de los dos canales. La longitud mxima que puede soportar la lnea es de 24 metros, siendo posible conectar hasta 22 dispositivos. A veces no resulta adecuada la topologa anterior, una nica lnea recorriendo todo un automvil resultara en un cableado extenso, superando el tamao mximo permitido, por lo cual puede resultar ms prctico la siguiente topologa tipo estrella como se puede ver en la figura 2.66.

FernandoArielBeunza79156

69

Tesis de Grado en Ingeniera Informtica

Figura 2.66. Topologa estrella pasiva [FlexRay].

En la topologa estrella, el cableado su puede ramificar, sin necesidad de depender de una sola lnea como ocurre con la topologa lineal. Solamente se permite un punto de empalme, y las limitaciones en cuando al tamao del cable y la cantidad de dispositivos es idntica a la topologa lineal. Para extender el lmite de longitud del cable, FlexRay permite la utilizacin de elementos activos. En la figura 2.67 y 2.68 se proponen dos variantes de la topologa estrella activa.

Figura 2.67. Topologa estrella activa clsica [FlexRay].

Figura 2.68. Topologa estrella activa modificada [FlexRay].

A diferencia de la topologa estrella pasiva, la estrella activa emplea en los puntos de empalme elementos repetidores. Los repetidores se encargan de regenerar la seal y tiene la capacidad de desconectar un tramo averiado del cableado, permitiendo el funcionamiento del resto de la red. La longitud mxima de cable que puede existir entre un dispositivo y un repetidor, o entre dos repetidores es de 24 metros. Sobre una misma lnea se pueden colocar hasta dos repetidores, lo que 70 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica permitira una distancia mxima entre dispositivos de 72 metros (3 tramos de 24 con dos repetidores de por medio). A partir de las topologas anteriores, pueden implementarse combinaciones resultando topologas hbridas, que no son recomendables ya que las limitaciones resultan de la combinacin de las limitaciones de las topologas bsicas.

Figura 2.69. Topologa hbrida [FlexRay].

La figura 2.69 muestra una topologa parte estrella y parte lineal, empleando elementos repetidores en los puntos de empalme de las diversas topologas bsicas utilizadas. Una trama de capa fsica se compone bsicamente de una secuencia de bytes como se puede observar en la figura 2.70.

Figura 2.70. Estructura de trama fsica [FlexRay].

La trama comienza con el envo de una secuencia de bits de valor cero utilizados para indicar el inicio de una transmisin. Luego de la secuencia anterior, se enva un bit de valor uno para indicar el comienzo de la trama. A continuacin se transmiten los bytes de la trama, con un encabezado previo compuesto por un bit de valor uno seguido de un bit de valor cero, utilizado para sincronizar el receptor. Una vez finalizada la transmisin de todos los bytes de la trama, se enva un bit de valor cero seguido de un bit de valor uno para indicar el fin de la trama.

2.2.7.2. Capa lgica


La capa lgica se encuentra ubicada por encima de la capa fsica y la capa de aplicacin residente el microcontrolador del dispositivo. Se encuentra implementada por el Controlador de Comunicaciones mencionado con anterioridad (ver figura 2.64), y es responsable del armado y desarmado de las tramas, controlar el acceso al medio y sincronizar el reloj interno. FernandoArielBeunza79156 71

Tesis de Grado en Ingeniera Informtica Para controlar el acceso al medio, FlexRay se basa en un ciclo de comunicacin recurrente conformado por cuatro segmentos. Los ciclos se pueden configurar de diferente manera como se puede observar en la figura 2.71.

Figura 2.71. Ciclos de comunicacin [FlexRay].

El segmento esttico se compone de ranuras de tiempo de longitud fija, cada uno asociado a un determinado identificador de trama, y a su vez cada identificador se encuentra asociado a un nodo determinado, de ste modo cada nodo conoce en que ranura debe transmitir. El segmento dinmico se compone de ranuras dinmicas de longitud variables, y el uso se determina en base a la prioridad de la trama a enviar. El segmento SW es utilizado para evaluar el estado medio. El segmento NT corresponde a un perodo de tiempo en el cual el canal queda libre. Tanto el segmento esttico como el segmento NT son obligatorios, en cambio el segmento dinmico y el segmento SW puede estar o no dentro de un ciclo. La informacin se enva por medio de tramas conformadas por los campos detallados en la figura 2.72. Una trama puede dividirse en tres partes: un encabezado, la informacin a enviar y cdigos de deteccin de errores. El tamao de la trama puede variar entre los 8 y 262 bytes.

Figura 2.72. Estructura de trama lgica [FlexRay].

El encabezado tiene una longitud de 5 bytes distribuidos en: 5 bits de estado, 11 bits destinados al identificador nico de trama asociado al nodo que enva la trama, 7 bits para indicar la cantidad de bytes de informacin enviados en la trama, 11 bits para cdigo de deteccin de errores CRC para el encabezado y 6 bits para indicar el ciclo de comunicacin corriente. La informacin conformarse

72

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica por 0 y 254 bytes de datos. Los cdigos de deteccin de errores se componen de tres cdigos CRC de 8 bits cada uno. FlexRay, como otros sistemas, tambin implementa un mecanismo de ahorro de energa, en donde los dispositivos se desactivan cuando no llevan a cabo ninguna tarea. Esto implica que antes de enviar una trama, deben activarse los dispositivos desactivados para que puedan recibir la trama.

2.3. Redes PLC en automviles


Todos los estndares referidos a PLC tratados hasta este momento fueron diseados para funcionar sobre redes elctricas presentes infraestructura edilicia. Algunos de stos estndares se encuentran ms orientados a la interconexin de sensores y actuadores, mientras que otros estndares proponen una alternativa a las tradicionales redes de datos cableadas (por ejemplo Ethernet) e inalmbricas (WiFi). Tambin se hizo referencia a los estndares de redes de datos empleadas en automviles, que no se encuentran, en principio, relacionados con la tecnologa PLC, pero las soluciones que aportan son de gran utilidad para poder adaptar la tecnologa PLC al ambiente de un automvil. Un automvil presenta caractersticas muy diferentes a una infraestructura edilicia, comenzando por la alimentacin, que en el caso de un automvil se trabaja con corriente continua a diferencia de una red elctrica domiciliaria. Muchos de los estndares PLC utilizan la seal alterna de potencia para sincronizacin, cosa que no es posible con una seal continua. Como sta diferencia, existen otras, que muestran la necesidad de realizar un trabajo de adaptacin para trasladar la tecnologa PLC al mundo del automvil.

2.3.1. DC-BUS
La empresa Yamar Electronics Ltd. ha desarrollado un sistema propietario para comunicaciones PLC para automviles. El sistema llamado DC-BUS permite un ahorro en el cableado que se traduce en una reduccin en el peso total del automvil adems de las ventajas que brinda la utilizacin de un bus de datos para intercomunicar los diversos dispositivos electrnicos existentes en el mismo.

2.3.1.1. mbitos de aplicacin


Las comunicaciones en un automvil por medio de un bus de datos pueden dividirse en tres categoras, segn el mbito de aplicacin:

Bus de alta velocidad para sistemas de multimedia y entretenimiento con velocidades entre 1 y 100 Mbps. Bus de velocidad media dedicado a telemtica con velocidades entre 10 Kbps y 1 Mbps. Bus de baja velocidad dedicado a mecatrnica con velocidades entre 1 Kbps y 10 Kbps.

DC-BUS propone una opcin por cada categora. Para las aplicaciones multimedia existe una alternativa que ofrece 1,7 Mbps utilizada, por ejemplo, para transmitir audio de calidad proveniente del cargador de CD hacia el reproductor de audio. Para aplicaciones de telemtica, la alternativa existente tiene una velocidad de 250 Kbps que permite la transmisin de voz y datos. Por ltimo, FernandoArielBeunza79156 73

Tesis de Grado en Ingeniera Informtica para aplicaciones de mecatrnica, se ofrece una alternativa de 10 Kbps adecuada para intercomunicar sensores y actuadores.

Figura 2.73. Esquema del DC-BUS desarrollado por Yamar Electronics Ltd.

2.3.1.2. Medio de comunicacin


Para cada una de las categoras mencionada con anterioridad se asignan diferentes frecuencias de trabajo: (F0) para mecatrnica, (F1, F2) para telemtica y (F3, F4) para multimedia; siendo utilizadas dos frecuencia para redundancia.

Figura 2.74. Canales utilizados por DC-BUS [Maryanka00].

DC-BUS fue diseado para trabajar en una red constituida con hasta 16 dispositivos. Todos los canales se encuentran disponibles sobre una misma red de potencia. Solamente un dispositivo a la vez, puede enviar informacin utilizando cualquiera de los canales. Cuando varios dispositivos tiene que realizar una transmisin, se emplea un protocolo CSMA para resolver la contienda entre los dispositivos. Existen variantes del protocolo CSMA, sobre el tratamiento de las colisiones de mensajes. DC-BUS tiene la particularidad de no poder transmitir y recibir en forma simultnea, lo cual impide la deteccin de colisin. La solucin implementada consiste en realizar un arbitraje previo a la transmisin, y resolver la contienda en base a la emisin y deteccin de una portadora.

Figura 2.75. Transmisin de un mensaje DC-BUS [AnraniRubin].

74

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica En la figura 2.75 su puede observar la existencia de un perodo de arbitraje destinado a resolver la contienda entre varios dispositivos que deseen transmitir en forma simultnea. El perodo de arbitraje comienza cuando no se detecta activa en el canal de comunicacin. El mecanismo de resolucin de contienda consiste en que cada dispositivo contiene un registro de n bits cuyos valores se determinan aleatoriamente. Dicho registro, determina en que momento el dispositivo debe emitir la portadora (bit uno) y cuando debe escuchar el canal (bit cero), durante un tiempo equivalente al perodo de un bit, a medida que se recorre el registro. El primer y ltimo bit del registro tienen valor cero, indicando que debe escuchar el canal al comienzo y fin del recorrido. Luego de haber recorrido los n bits del registro, si en ningn momento de escucha del canal se detect la presencia de portadora, el dispositivo inicia la transmisin. En caso contrario, debe retornarse al punto inicial y volviendo a iniciar el perodo de arbitraje.

2.3.1.3. Implementacin
Un dispositivo de comunicacin DC-BUS se encuentra constituido por los bloques enumerados en la figura 2.76.

Figura 2.76. Arquitectura de DC-BUS [Maryanka00].

La informacin proveniente de un sensor, u otro dispositivo generador de datos, es almacenada en una cola de transmisin. La informacin de la cola, es empaquetada en un mensaje y se le agrega un cdigo corrector de errores, y queda a la espera de poder ser modulada y enviada cuando el canal se encuentre disponible. Los receptores del mensaje demodulan la seal recibida, corrigen los errores ocurridos, desarman el mensaje y almacenan en la cola de recepcin la informacin recibida, que queda a la espera de que el dispositivo cliente destinatario pueda recibirla.

2.3.2. Trabajos sobre PLC en la industria automotriz


La Facultad de Ingeniera Elctrica de la Universidad Tcnica Checa de Praga ha realizado una serie de trabajos sobre la implementacin tecnologa PLC en el ambiente automotriz. En uno de stos trabajos, Power Line Communications in Automotive Industry [Trnka05], se implementa un FernandoArielBeunza79156 75

Tesis de Grado en Ingeniera Informtica dispositivo que permite la comunicacin por medio del cableado elctrico del automvil. Dicho trabajo adems realiza un estudio de las caractersticas del canal de comunicacin utilizado y del desempeo de diversas tcnicas de modulacin para la transmisin de datos. El dispositivo mencionado anteriormente consiste en un modem prototipo implementado con un FPGA como se describe en el trabajo Development System for Communications over DC Power Lines [TrnkaPurkert05]. Un ltimo trabajo realizado por la misma universidad, Optimization of the Data Transmissions over DC Power Lines [Trnka06-1] [Trnka06-2], pone nfasis en el mecanismo de transmisin de los datos. Propone dos tcnicas de modulacin basadas en BFSK y BPSK, las cuales son adaptadas para funcionar sobre lneas de potencia. Los trabajos mencionados anteriormente ponen su atencin en implementar con un bajo nivel de complejidad las capas fsica y de enlace, dejando de lado las restantes capas del modelo OSI.

2.3.2.1. Canal de comunicaciones


Segn el estudio realizado en el trabajo Optimization of the Data Transmissions over DC Power Lines [Trnka06-2], el canal de comunicaciones utilizado por las redes PLC introduce en la seales de informacin distorsiones lineales y no lineales. Dentro del grupo de las distorsiones lineales se encuentran las referidas al ruido aditivo, atenuacin de seal, distorsin de amplitud y fase, y distorsin multitrayecto. Las distorsiones del tipo no lineal, se refieren principalmente a limitaciones de los amplificadores, la utilizacin de transformadores con ncleo ferromagntico y circuitos limitadores. Una aproximacin terica del canal de comunicaciones, que tenga en cuenta solamente las distorsiones lineales, se puede modelizar por medio de una funcin de transferencia y la suma de ruido aditivo a la respuesta de dicha funcin, como se puede observar en la figura 2.77.

Figura 2.77. Modelo del canal de comunicaciones [Trnka06-2].

La funcin de transferencia H(f, t) representa la atenuacin de seal, distorsin de amplitud y fase, y distorsin multitrayecto en funcin de la frecuencia f y del tiempo t. Dicha funcin es dependiente del tiempo debido a que la respuesta en frecuencia del canal de comunicaciones depende de la estructura de la red de potencia que vara segn se activen o desactiven dispositivos conectados a sta (por ejemplo, el encendido o apagado de una lmpara, un motor, u otro tipo de dispositivo que consuma energa de la red de potencia afectan la impedancia total de la misma). Adems de la dependencia temporal de la funcin de transferencia H(f, t), la respuesta en frecuencia del canal de comunicaciones no es invariante a la ubicacin del transmisor y el receptor dentro de la red de potencia, por lo cual se tendrn diferentes funciones H segn la ubicacin del transmisor y receptor. Para corroborar la validez del modelo de canal de comunicaciones propuesto anteriormente, se toma una red de potencia de un automvil (que segn [Trnka06-2] pertenece al Skoda Fabia), y

76

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica se definen puntos de prueba, a fin de determinar en forma aproximada la respuesta en frecuencia de la red.

Figura 2.78. Esquema bsico de una red de potencia de un automvil y puntos de prueba [Trnka06-2].

En la figura 2.78 se detallan seis puntos de prueba que comprenden todo el automvil, a fin de obtener la atenuacin promedio en diferentes bandas de frecuencia del canal de comunicaciones entre cada una de las posibles combinaciones de puntos. Segn las mediciones realizadas en el trabajo Optimization of the Data Transmissions over DC Power Lines [Trnka06-2], los valores de atenuacin promedio, para cada una de las diferentes bandas de frecuencia, son los detallados en la tabla 2.16.

Tabla 2.16. Atenuacin promedio (en dB) en diferentes bandas de frecuencia [Trnka06-2].

Como se puede observar en la anterior tabla, la atenuacin promedio vara aproximadamente entre las -50 y -20 dB, resultando la banda de frecuencia comprendida entre los 0 y 5 MHz, como la banda con mayor atenuacin, y la banda de frecuencias comprendida entre los 15 y 20 MHz, como la banda con menor atenuacin, de lo cual se deduce que el rango de frecuencias ms ptimo para establecer comunicaciones PLC es el comprendido entre los 15 y 20 MHz. Otra caracterstica del canal de comunicaciones a tener en cuenta es la impedancia de la red de potencia, ya que sto define la potencia requerida por los transmisores. Para obtener dicha impedancia, en el trabajo Power Line Communications in Automotive Industry [Trnka05], se FernandoArielBeunza79156 77

Tesis de Grado en Ingeniera Informtica realizan mediciones de la impedancia de la red en los puntos de prueba 2 y 3 de la figura 2.78 correspondientes a la puerta del conductor y acompaante, respectivamente.

Figura 2.79. Impedancia de la red de potencia en funcin de la frecuencia [Trnka05].

Como se puede observar en la figura 2.79, la impedancia de la red de potencia en funcin de la frecuencia es similar en ambos puntos de pruebas, lo que permite inferir que ste parmetro de la red de potencia es invariante a la ubicacin (al contrario de lo que ocurre con la respuesta en frecuencia). Adems se establece como rango apto para comunicaciones PLC el comprendido entre las frecuencias 4 y 30 MHz, ya que el valor mnimo de la impedancia ronda los 10 ohm. Las frecuencias debajo de los 4 MHz, no resultan convenientes ya que el valor de la impedancia cae de los 10 ohm, lo que hace necesario que los modems requieran de transmisores de considerable potencia. Por ltimo, en el trabajo Power Line Communications in Automotive Industry [Trnka05], se evala el funcionamiento de un modem prototipo. En dicha prueba se compara la seal emitida por el transmisor y la seal recibida por el receptor, y en los resultados obtenidos se puede observar la atenuacin producida por la red de potencia en la seal original.

Figura 2.80. Seal transmitida (arriba) y su espectro (abajo) [Trnka05].

Figura 2.81. Seal recibida (arriba) y su espectro(abajo) [Trnka05].

78

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica Como se observa en las figuras 2.80 y 2.81, de una seal cuyo espectro se encuentra comprendido entre las frecuencias 4 y 16 MHz, solamente llegan al receptor las frecuencias comprendidas entre los 12 y 16 MHz, lo que obedece a los valores de atenuacin promedio en funcin de la frecuencia estudiados con anterioridad (ver tabla 2.16). Luego de analizar los resultados obtenidos en los trabajos realizados por la Facultad de Ingeniera Elctrica de la Universidad Tcnica Checa de Praga, se pueden concluir que el canal de comunicaciones presenta las siguientes caractersticas:

Debido a la impedancia de la red de alimentacin de un automvil, el rango de frecuencias utilizable se encuentra comprendido entre los 4 y 30 MHz. Debajo de los 4 MHz, la impedancia alcanza valores menores a 10 ohm, lo cual requiere modems con transmisores de considerable potencia. Por arriba de los 30 MHz se excede el lmite de la banda de HF destinada para comunicaciones PLC [Trnka05]. La banda de frecuencias comprendida entre 4 y 30 MHz, destinada para comunicaciones PLC, coincide con la banda de HF caracterizada por desvanecimiento intermitente y selectivo de frecuencia, y trayectoria de propagacin mltiple [OppenheimWillsky97]. El rango de frecuencias con menor atenuacin se encuentra comprendido entre los 15 y 20 MHz, lo que resulta en el rango ms ptimo para implementar comunicaciones PLC. sto no implica descartar las frecuencias prximas a dicho rango ptimo. La pruebas realizadas al modem prototipo, han dado como resultado que de una seal emitida comprendida en frecuencia entre los 4 y 16 MHz, slo llegan al receptor las frecuencias comprendidas dentro del rango de los 12 y 16 MHz aproximadamente (figuras 2.80 y 2.81). sto obedece a lo enunciado en la caracterstica anterior.

2.3.2.2. Mtodo de acoplamiento


Como se comparte una misma red cableada para el suministro alimentacin e intercambio de informacin entre los dispositivos conectados a ella, se requiere un mecanismo en el transmisor que permita el acoplamiento de la seal con informacin, a la red de alimentacin y un mecanismo en el receptor que filtre, dejando pasar solamente la seal con informacin. Bsicamente existen dos mtodos de acoplamiento, que dependen del elemento pasivo utilizado, denominados: acoplamiento capacitivo y acoplamiento inductivo.

Figura 2.82. Acoplamiento capacitivo [Trnka06-2].

Figura 2.83. Acoplamiento inductivo [Trnka06-2].

FernandoArielBeunza79156

79

Tesis de Grado en Ingeniera Informtica El mtodo de acoplamiento capacitivo, tambin se lo denomina acoplamiento paralelo, debido a que la fuente de seal se conecta en paralelo a la aplicacin. ste mtodo se caracteriza por ser una solucin de bajo costo e insensible a las variaciones de corriente, pero resulta sensible a aplicaciones de baja impedancia. Para disminuir ste ltimo efecto se suele agregar una inductor como se puede observar en la figura 2.82. En cambio, el mtodo de acoplamiento inductivo, se lo denomina acoplamiento serie, debido a que la fuente de seal se conecta en serie a la aplicacin por medio de un transformador. ste mtodo tiene la ventaja de ser insensible a aplicaciones de baja impedancia, pero tiene el defecto de ser sensible a las variaciones de corriente. Para contrarrestar ste efecto, se suele agregar un capacitor en paralelo a la aplicacin (figura 2.83). En el modem prototipo propuesto en el trabajo Optimization of the Data Transmissions over DC Power Lines [Trnka06-2], se implementa tambin una variante del acoplamiento capacitivo compuesto por dos capacitores en serie a la salida del transmisor, que junto a la impedancia de salida de ste ltimo conforma un filtro pasa alto.

2.3.2.3. Tcnica de modulacin


Luego de estudiar las caractersticas propias del canal de comunicacin utilizado para redes PLC, se debe hallar la tcnica de modulacin ms adecuada que permita la transmisin de datos de forma confiable sobre un medio hostil como el descripto con anterioridad. Adems de encontrar una tcnica de modulacin robusta, no se debe olvidar el factor de simplicidad de implementacin, ya que es uno de los objetivos del presente trabajo. La tcnica de banda base, tal vez sta tcnica pueda ser considerada como la ms simple de todas ya que consiste en representar la informacin binaria por medio de dos estados elctricos. Sin embargo, si se realiza un anlisis del espectro de la seal de informacin, la mayor cantidad de energa de dicha seal se concentra en las frecuencias ubicadas por debajo de los 4 MHz, que cuando se estudiaron las caractersticas del canal de comunicacin, se determin que dicha zona del espectro no es la ms adecuada para transmitir informacin (por cuestiones de atenuacin, impedancia, etc.). sto ltimo, concluye con la necesidad de transmitir la informacin sobre una o varias portadoras de frecuencia superior a los 4 MHz, para proteger a la informacin de las distorsiones existentes en la zona del espectro en cuestin. Por lo cual, con sto, queda totalmente descartada la posibilidad de utilizar la tcnica de banda base, ya que no brinda un mecanismo de transmisin de informacin de forma confiable. Las tcnicas de banda de paso se caracterizan por utilizar una o varias portadoras para transportar la informacin. De sta forma, la o las portadoras trasladan la informacin a un rango de frecuencias superior a la ocupada por la seal de informacin, delimitando la misma a una banda de frecuencias del espectro. En funcin del ancho de la banda de frecuencias utilizada, se pueden distinguir dos tipos de tcnicas diferentes: banda estrecha y banda ancha. Las tcnicas de banda estrecha se basan en la utilizacin de una sola frecuencia portadora lo cual resulta aceptable si el objetivo es el bajo costo y la velocidad de transmisin no es demasiada alta. Dependiendo de la tcnica de modulacin, pueden ser ms o menos confiable, pero en general son susceptible a las interferencia y a los desvanecimientos de frecuencia caractersticos del canal de comunicaciones de la redes PLC. La tcnica de modulacin de banda estrecha ms simple de implementar es la modulacin en amplitud. sta tcnica consiste en disponer de una portadora cuya amplitud vara segn la informacin a transmitir. La variante ms simple es la denominada ASK que define dos niveles de amplitud posibles: uno destinado para transmitir un bit cero y otro para transmitir un bit uno). 80 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica Debido a que sta tcnica resulta bastante ineficiente se ha desarrollado una mejora que trabaja con ms niveles de amplitud y tambin trabaja con la fase de la portadora, logrando una mejora en la eficiencia, que se conoce como QAM. Como se mencion en el estudio de las caractersticas del canal de comunicaciones, una de ellas es la distorsin de amplitud y fase, que afecta a los esquemas de modulacin basados en la amplitud, por lo cual resultan alternativas inviables para las comunicaciones PLC. Debido a las dificultades existentes en transmitir la informacin por medio de la amplitud de la portadora, nace la modulacin en frecuencia que consiste en variar las frecuencia de la portadora de amplitud constante en funcin de la informacin a transmitir. La versin ms simple se la conoce como BFSK, en donde se destina una frecuencia para codificar un bit de valor cero y otra frecuencia para codificar un bit de valor uno. sta tcnica resulta se inmune ante las distorsiones de amplitud y fase enunciada con anterioridad, pero no resuelven otra caracterstica del canal de comunicaciones que son los desvanecimientos de frecuencia, resultando inadecuada sta tcnica si dicho fenmeno coincide con una de las frecuencias utilizadas.

Figura 2.84. Diagrama de bloques de un modem BFSK coherente [Trnka06-2].

Como alternativa a las anteriores tcnicas de modulacin, existe la modulacin en fase, en la cual la informacin se codifica por medio de la fase de la portadora. sta tcnica resulta ser ms confiable que las dependientes de la amplitud (la amplitud de la portadora es constante) y ms eficiente que las dependientes de la frecuencia (se utiliza una sola frecuencia), utilizando en su versin ms simple, conocida como BPSK, una fase de la portadora para codificar un bit de valor cero y la fase opuesta para codificar un bit de valor uno. Si bien resulta una mejora, la complejidad del demodulador crece ya que se requiere de un recuperador de portadora.

Figura 2.85. Diagrama de bloques de un modem BPSK coherente [Trnka06-2].

Una variante que elimina la necesidad de implementar un recuperador de portadora es la conocida como DBPSK y requiere anteponer un codificador diferencial al modulador, que no incrementa demasiado la complejidad de ste ltimo. El precio que se debe pagar por esta ventaja es una menor inmunidad al ruido con respecto a la ofrecida por la tcnica original.

FernandoArielBeunza79156

81

Tesis de Grado en Ingeniera Informtica

Figura 2.86. Diagrama de bloques de un demodulador DBPSK [Trnka06-2].

Para aumentar la eficiencia de las tcnicas anteriores pueden utilizarse ms de dos fase para codificar la informacin, aumentando la capacidad de transporte, pero disminuyendo la inmunidad al ruido. En el caso particular de las comunicaciones PLC, no se pueden emplear muchas fases (disminucin de la inmunidad al ruido), y ninguna de las variantes es inmune al desvanecimiento de frecuencia que si coincide con la portadora, imposibilita la transmisin de informacin a travs del medio. Debido a los problemas expuestos en las anteriores tcnicas de modulacin, resulta necesario transmitir la informacin de forma redundante, trabajando con mltiples portadoras independientemente de la tcnica de modulacin. sto disminuye la posibilidad de destruccin de la seal de informacin a mayor cantidad de portadoras se utilicen. La utilizacin de mltiples portadoras implica una aumento del ancho de banda requerido, por ello, las tcnicas que se describen a continuacin se denominan tcnicas de modulacin de banda ancha. La primer tcnica de modulacin de banda ancha es una mejora de la modulacin BPSK basada en la tcnica de espectro ensanchado de secuencia directa conocida como DSSS. El principio fundamental de cualquier tcnica de ensanchamiento de espectro se basa en la idea de distribuir la energa de la seal concentrada en una banda estrecha a lo largo de una banda ms ancha que la anterior, con lo cual se mejora la inmunidad al ruido y resistencia a la interferencia. En el caso particular de la tcnica DSSS, dicha distribucin se logra con la introduccin de una secuencia pseudoaleatoria, con lo cual en lugar de transmitir un bit cero o uno directamente (como en el caso de BPSK), se transmite una secuencia pseudoaleatoria que representa el bit de informacin. Dicha secuencia modulan y demodulan de forma idntica a la tcnica BPSK.

Figura 2.87. Diagrama de bloques de un modem DSSS [Trnka06-2].

La mejora introducida por sta ltima tcnica de modulacin agrega a las caractersticas de la modulacin BPSK de banda estrecha los beneficios del ensanchamiento en espectro que hace resistente a la informacin al ruido e interferencia propios del canal de comunicaciones, sin un gran incremento de la complejidad de implementacin. Pero la atenuacin en funcin de la frecuencia caracterstica del canal de comunicaciones, estudiada con anterioridad, implica la necesidad de implementar un esquema de ecualizacin para corregir las deformaciones del espectro de la seal, para que sta pueda ser demodulada de forma correcta. La desventaja de la tcnica DSSS radica en que requiere una alto grado de complejidad la implementacin de un ecualizador que permita el correcto funcionamiento sobre el canal de comunicaciones PLC particular de un automvil. sto

82

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica ltimo es lo que hace descartar sta tcnica a pesar de que es viable para comunicaciones PLC en otros entornos de aplicacin. Otra tcnica de modulacin de banda ancha utilizada para comunicaciones PLC es la OFDM, que consiste en trabajar con mltiples portadoras. sto minimiza los efectos indeseados sobre la seal de informacin ocasionados por la naturaleza del canal de comunicaciones empleado. De modo similar a la anterior tcnica, OFDM trabaja junto con alguna de la tcnicas de modulacin mencionadas en el momento que se trataron las tcnicas de modulacin de banda estrecha; como por ejemplo variantes de modulacin en fase (BPSK, QPSK, etc.) o QAM. El principio de funcionamiento bsico se describe en la figura 2.88, que consiste en un modulador y demodulador de alguna de las tcnicas de banda estrecha, que en lugar de unirse directamente se interpone un bloque IDFT, encargada de transformar la seal generada por el modulador en un smbolo compuesto por mltiples portadoras, y un bloque DFT, que toma el smbolo generado y lo convierte en la seal original generada por el modulador.

Figura 2.88. Diagrama de bloques de un modem OFDM [Trnka06-2].

sta tcnica descripta simplifica la implementacin del ecualizador, ya que el espectro generado (cuya forma se aproxima a un rectngulo) es ms simple reconstituir que el generador por la tcnica DSSS. Sin embargo, la complejidad de implementar los bloques IDFT y DFT, hacen de ste mtodo, que aparenta ser ms adecuado de todos los estudiados, que en realidad no lo sea. Hasta aqu se han analizado las tcnicas de modulacin ms conocidas, y ninguna de ellas satisface completamente las necesidades requeridas en las comunicaciones PLC en automviles. Por sta razn, a continuacin se analizan otras tcnicas que surgen como modificaciones a las anteriormente analizadas.

2.3.2.4. Tcnicas modificadas


En los trabajos realizados por la Facultad de Ingeniera Elctrica de la Universidad Tcnica Checa de Praga sobre este tema, se proponen dos tcnicas de modulacin que pretenden reunir las simpleza de las tcnicas de banda estrecha con la robustez de las tcnicas de banda ancha. La primer tcnica de modulacin que se presenta consta de una modificacin de la tcnica BFSK, que se la designa BFSK Adaptado. El principio de funcionamiento es simple como el de BFSK, pero en lugar de emplear una portadora para codificar cada bit de valor cero o uno, se emplean varias (en este caso se utilizan las portadoras pares e impares). Por lo tanto, el espectro de la seal de informacin es similar al que se puede obtener con la tcnica OFDM, ya que se definen dos smbolos (uno con las portadoras pares y otro con las impares) para transmitir un bit de valor cero o uno. La diferencia de sta tcnica con respecto a OFDM es que los smbolos se encuentran predefinidos por medio de un conjunto de muestras, y no se generan durante el funcionamiento, ahorrando la complejidad requerida para implementar los bloques IDFT y DFT.

FernandoArielBeunza79156

83

Tesis de Grado en Ingeniera Informtica

Figura 2.89. Diagrama de bloques de un modem BFSK Adaptado [Trnka06-2].

La tcnica BFSK Adaptada logra reunir la simpleza del BFSK con las ventajas de OFDM, pero la utilizacin del espectro no es del todo eficiente, ya que para cada uno de los smbolos solamente se utilizan la mitad de las portadoras disponibles. El empleo de ms portadoras se traduce en una mayor redundancia lo que se traduce en mayor confiabilidad en el proceso de transmisin de la informacin. Para lograr el uso de todas las portadoras disponibles, se propone una nueva tcnica basada en DBPSK, denominada DBPSK Adaptada. Al igual que la anterior, sta tcnica se basa en la modulacin DBPSK, pero en lugar de trabajar con una sola portadora, utiliza todas las portadoras disponibles. Bsicamente se dispone de un smbolo sintetizado conformado por todas las portadoras disponibles a ste se le modifica su fase segn el bit que se transmita. Por lo cual, adems de las ventajas de BFSK Adaptado, se le suma uso de todas las portadoras (que se traduce en mayor redundancia y confiabilidad) y la necesidad de tener generado previamente un slo smbolo.

Figura 2.90. Diagrama de bloques de un modem DBPSK Adaptado [Trnka06-2].

sta tcnica podra adaptarse a BPSK (que es mejor que DBPSK), pero como la primera requiere de un recuperador de portadora, una tcnica BPSK Adaptada requerira de un recuperador de todas las portadoras utilizadas lo cual incrementara el costo de implementacin.

84

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

3. Descripcin del problema


En este captulo se realiza una comparacin entre las soluciones existentes presentadas en el captulo anterior, y se analiza el alcance de cada una de ellas, para determinar los problemas no resueltos a fin de presentar una propuesta de solucin algunos de stos ltimos. Los antecedentes estudiados pertenecen en su mayora a dos ambientes diferentes. Las comunicaciones PLC se desarrollan sobre el ambiente de infraestructura edilicia, diferente a las redes de datos utilizadas en el ambiente de los automviles. Existen antecedentes sobre la integracin de tecnologas de ambos ambientes, que brindan un punto inicial para continuar trabajando sobre ste tema. El presente trabajo pretende contribuir en sta materia.

3.1. Alcance de las soluciones existentes


En general, los estndares existentes, tanto sobre tecnologa PLC como redes de datos para automviles, no implementan todas las capas propuestos por el modelo OSI, salvo algunas excepciones. Algunos estndares se centran en implementar solamente las capas fsica y de enlace, pudiendo o no dar libertad de eleccin del medio fsico utilizado como canal de comunicaciones; otros en cambio, implementan algunas de las capas superiores con la posibilidad de trabajar con los estndares de primer tipo; y finalmente existen los estndares que implementan todas las capas del modelo OSI, permitiendo incluso emplear diversos medios fsicos como canal de comunicaciones.

3.1.1. Comunicaciones PLC


Las comunicaciones PLC se encuentran reguladas por la norma CENELEC 50065, que establece rango de frecuencias reservado para este tipo de comunicaciones. Los estndares que no requieren demasiado ancho de banda, utilizados para sensores y actuadores, respetan la normativa anterior. Los estndares ms evolucionados, generalmente empleados para transmisin de datos, se ven forzados a trabajar en otro rango de frecuencias para brindar mayor velocidad de transferencia. Entre los estndares del primer tipo se pueden mencionar: X10, UPB y LonWorks; mientras que entre los estndares que no respetan CENELEC 50065 se pueden destacar: CEBus y HomePlug. Los estndares X10, y su evolucin UPB, implementan las funcionalidades correspondientes a la capas fsica y de enlace segn el modelo OSI. Solamente permiten la utilizacin de un nico medio fsico, que en este caso son las lneas de energa. Se caracterizan por su simpleza, para se implementados en dispositivos de bajo costo. El estndar CEBus es similar a X10 y UPB, con respecto a las aplicaciones que hacen uso de ste estndar. La diferencia radica en que CEBus puede trabajar sobre diversos medios fsicos, entre los cuales se encuentran las lneas de potencia. LonWorks es el nico estndar PLC de los analizados en el captulo anterior que implementa todas las capas del modelo OSI, porque se basa en el protocolo CNP que define las siete capas. Al igual que CEBus, define en su capa fsica un conjunto de medios fsicos sobre los cuales se puede trabajar, entre los cuales figura las lneas de electricidad. Comparado con X10, UPB y CEBus, LonWorks es el estndar que brinda mayor funcionalidad, y tambin es el ms complejo de implementar. Por ltimo se encuentra la familia de especificaciones HomePlug, que originalmente se encontraban orientadas a brindar soporte para la creacin de redes IP empleando como medio de FernandoArielBeunza79156 85

Tesis de Grado en Ingeniera Informtica transmisin de datos las lneas de energa. Existen tres especificaciones, siendo la primera de ellas (HomePlug 1.0) la que fue orientada para el propsito descripto anteriormente. La segunda especificacin (HomePlug AV) introduce un conjunto de mejoras que adems de brindar soporte para redes IP, permite el transporte de audio y video. Finalmente, la tercer especificacin (HomePlug Green PHY) se encuentra orientada a control de dispositivos como X10, UPB, CEBus y LonWorks.

3.1.2. Redes de automviles


Los estndares de redes de datos para automviles descriptos en el captulo anterior generalmente implementan las capas inferiores (fsica y de enlace) del modelo propuesto por OSI. Las redes CAN y J1850 son las ms utilizada en la industria automotriz, aunque existen otros tipo de redes ms evolucionadas con mayores capacidades, empleadas en vehculos de alta gama, que requieren de la implementacin de ms capas del modelo OSI. CAN y J1850 se tratan de dos redes que presentan un funcionamiento similar aunque las prestaciones que ofrecen son diferentes. Siguiendo el modelo de capas propuesto por OSI, ambas redes implementan las capas fsica y de enlace; y adems J1850 implementa la capa de aplicacin que consisten en una interfaz para interactuar con los dispositivos. Las especificaciones de CAN son independientes del medio fsico utilizado como canal de comunicaciones, mientras que J1850 especifica que el medio fsico debe ser cableado elctrico con diversas configuraciones segn la variante utilizada (VPW o PWM). La topologa de red utilizada en el caso de ambas redes es tipo bus. Tanto las redes CAN como J1850, son redes del tipo multimaestro, por lo cual requieren de un protocolo de control de acceso al medio CSMA/CR que permite resolver las colisiones. Las redes CAN pueden trabajar en un rango amplio de velocidades de transferencia lo que extenderse a diversas aplicaciones dentro de un automvil (aplicaciones de propsito general y tiempo real). En cambio J1850 se encuentra preparado solamente para aplicaciones de propsito general, ya que la limitada velocidad de transferencia que ofrece no soporta aplicaciones de tiempo real. Ambas redes se encuentran orientadas a control, por lo cual se prioriza la robustez y simpleza de implementacin, sobre tener gran capacidad para transporte de datos. Las redes LIN estn diseadas como complemento de otras redes como CAN y J1850. Solamente implementa las capas fsicas y de enlace. El medio fsico utilizado se compone de un nico cable. La topologa utilizada por ste tipo de redes es tipo bus, y el bajo costo se debe a la baja complejidad de implementacin que presenta gracias a que es una red del tipo maestro/esclavo, por lo cual tampoco se requiere de ningn protocolo de resolucin de colisiones. La idea de LIN no es brindar grandes capacidades de transferencia de datos, sino poder interconectar diversos dispositivos cercanos entre si a bajo costo. El estndar OSEK/VDX fue desarrollado con el objetivo de poder bajar los costos de los dispositivos y garantizar la interoperabilidad entre los mismos. La idea es proponer una plataforma de desarrollo de software reutilizable para dispositivos de un automvil que se intercomunican por medio de redes CAN o J1850. OSEK/VDX surge como un complemento de las dos redes anteriores implementando la capa de red del modelo OSI, sobre las capas de enlace y fsica provistas por CAN y J1850. Las redes D2B y MOST implementan las capas fsica y de enlace, y en el caso de MOST, tambin se implementa una capa de aplicacin por encima de la capa de enlace. El medio fsico utilizado en ambas redes es fibra ptica para la transferencia de datos y cableado elctrico para funciones auxiliares. Las prestaciones que brinda cada tipo de red difieren entre s, MOST supera a D2B por emplear una mejor calidad de cableado ptico que le permite aumentar la velocidad de transferencia, la longitud de la red y la cantidad de dispositivos conectados. La topologa utilizada 86 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica en ambas redes es anillo para el cableado ptico y estrella para el cableado elctrico, en donde existe un dispositivo que ejerce el rol de maestro de la red. El control de acceso al medio viene dado en ambas redes por el mtodo de paso de testigo, que consiste en un testigo que circula por medio del anillo que indica a cada dispositivo cuando transmitir, creando un canal de comunicacin libre de colisiones. El mtodo de paso de testigo exigen la existencia de un dispositivo supervisor de la red que el es dispositivo maestro, por lo cual D2B y MOST son redes del tipo maestro/esclavo. Tanto D2B como MOST se encuentran orientadas a aplicaciones multimedia donde se requiere gran capacidad de transporte de datos a alta velocidad. Las redes FlexRay fueron diseadas para superar los problemas que presentan las redes D2B y MOST, y proponer una mejora a las redes tradicionales CAN y J1850. De igual forma que las redes analizadas hasta ahora, FlexRay implementa dos capas equivalentes a la capa fsica y de enlace del modelo OSI. El medio fsico propuesto en este caso es cable par trenzado, lo cual lo hace una alternativa ms econmica y sin los inconvenientes presentados por la fibra ptica utilizada en D2B y MOST: Con respecto a la topologa, FlexRay permite utilizar configuraciones tipo bus, estrella o combinacin de las anteriores, lo que otorga una gran flexibilidad en este aspecto. Adems es una red multimaestro como CAN y J1850, eliminando las desventajas presentes en el esquema propuesto por D2B y MOST. El mtodo para controlar el acceso al medio consiste en ranuras de tiempo fijas asignadas a cada dispositivo para transmitir tramas de longitud fija, y en ranuras de tiempo variable empleadas para la transmisin de tramas de longitud variable, en donde se determina que dispositivo hace uso de ellas en base a la prioridad de la trama. En cuanto a capacidad de transporte y velocidad, se encuentra entre algo intermedio entre CAN y J1850, y D2B y MOST; resulta una gran mejora comparado con las capacidades prestadas por los dos primeros, pero no logra superar a los dos segundos.

3.1.3. PLC en automviles


Las comunicaciones PLC en el ambiente del automvil deriva del desarrollo realizado sobre ste tipo de comunicaciones para infraestructura edilicia analizado con anterioridad. Los requisitos de ste ambiente son diferentes, como tambin los problemas que se plantean a la hora de introducir una tecnologa diseada originalmente para un ambiente diferente. En el ste trabajo se estudia dos desarrollos sobre esta materia: uno es el estndar DC-BUS desarrollado por la empresa Yamar Electronics Ltd., y el otro son una serie de trabajos realizados por la Facultad de Ingeniera Elctrica de la Universidad Tcnica Checa de Praga. En ambos casos se implementan la capa fsica correspondientes al modelo OSI, y en el caso de DC-BUS tambin la capa de enlace, porque centran su esfuerzo en resolver las cuestiones involucradas a las comunicaciones sobre lneas de potencia, un medio fsico que conforma una red topologa hbrida, que no fue diseado para tal fin, brindado soporte para otras redes que implementen las restantes capas. DC-BUS es un desarrollo comercial que brinda la posibilidad de interconexin de dispositivos por medio de la lnea de alimentacin de un automvil. ste estndar de comunicacin PLC est pensado para brindar un puente entre las lneas de alimentacin y redes CAN, por lo cual implementa las capas fsica y de enlace con una interfaz que permite interactuar con CAN. Las redes DC-BUS, por trabajar con redes CAN, hereda su caracterstica de ser multimaestro, y el inconveniente de las colisiones que son resuelvas por un mecanismo de arbitraje diseado especialmente para ste estndar. DC-BUS es capaz de trabajar en rango de velocidad de transferencia baja, media y alta; lo que le permite trabajar con aplicaciones de control, de telemtica y multimedia, respectivamente. Los trabajos desarrollados por la Facultad de Ingeniera Elctrica de la Universidad Tcnica Checa de Praga, no son un desarrollo comercial como el caso de DC-BUS. Realizan un FernandoArielBeunza79156 87

Tesis de Grado en Ingeniera Informtica estudio sobre las caractersticas que presentan las lneas de alimentacin de un automvil, y como podran usarse stas para transmisin de informacin. Plantean el desarrollo de un prototipo que implementa las capas fsicas y de enlace, pero no define una interfaz para otras redes, como por ejemplo CAN, como lo hace DC-BUS. La capacidad de transferencia que brinda corresponde a aplicaciones de telemtica.

3.2. Requerimientos para la propuesta del presente trabajo


Como se menciona en el anlisis anterior, las soluciones existentes, en general, centran su atencin en implementar solamente las capas fsica y de enlace, dejando de lado las restantes capas del modelo OSI. Tomando como punto de partida los trabajos desarrollados por la Facultad de Ingeniera Elctrica de la Universidad Tcnica Checa de Praga sobre comunicaciones PLC en automviles, y las ideas propuestas por los estndares referente a PLC y redes de datos de automviles; el objetivo del presente trabajo es proponer una implementacin de las capas no implementadas, que son las ms relacionadas con la informtica. La idea es similar a lo propuesto por LonWorks que define las siete capas del modelo OSI, y a OSEK/VDX combinado con CAN o J1850 que brinda una plataforma estndar de comunicacin entre dispositivos. Aplicacin Presentacin Sesin Transporte Red Enlace Fsica ModemPLC Ncleodelsistema Dispositivocliente(realovirtual)

Figura 3.1. Modelo de capas del sistema.

El desarrollo del sistema debe respetar el modelo de capas sugerido por OSI y sus principales componentes pueden verse distribuidos en la figura 3.1. A diferencia de LonWorks u OSEK/VDX, todas las capas no se pueden implementar dentro de un nico microcontrolador, ya que se pretende separar las funcionalidades del dispositivo cliente con las relacionadas con las comunicaciones PLC, para no aumentar la complejidad del firmware del dispositivo cliente. El dispositivo cliente es el dispositivo que obtiene informacin suministrada por el sistema, hace uso de ella, emite alguna accin que puede ser fsica y/o una respuesta hacia el sistema. En este dispositivo deben implementarse las capas de aplicacin y presentacin debido a que la primera constituye una interfaz para la funcin especfica del dispositivo, que en caso particular de este trabajo es una funcionalidad demostrativa del funcionamiento del sistema; y la segunda se relaciona a la representacin de los datos que depende de la plataforma, por ejemplo se puede tener un dispositivo que enve un nmero entero a otro y cada uno de stos tiene una forma diferente de representarlos lo cual requiere de un proceso de adaptacin para la correcta interpretacin del dato en cuestin.

88

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica El ncleo del sistema debe comprender las capas de sesin, transporte y red. Es responsabilidad del sistema establecer, gestionar y finalizar las conexiones entre los dispositivos clientes (capa sesin). Adems el sistema debe garantizar, con distintos grados de confiabilidad, que la informacin generada por un dispositivo llegu a los dispositivos destinatarios (capa de transporte). Por ltimo, es responsabilidad del ncleo del sistema la identificacin de cada uno de los dispositivos presentes en el bus de datos y el encaminado de los paquetes de informacin (capa de red). El modem PLC es el dispositivo fsico encargado de transmitir y recibir informacin por medio del cableado elctrico (capa fsica) y de implementar el protocolo de acceso al medio fsico de comunicacin que permita la transmisin de datos sin errores (capa de enlace). Tanto el ncleo del sistema como el protocolo de enlace deben residir en el microcontrolador del modem PLC para aprovechar al mximo las funcionalidades de ste dispositivo electrnico bajando el costo en dinero del sistema.

Figura 3.2. Esquema de red.

En la figura 3.2 puede observarse el esquema general de la red de la cual slo es recomendable la implementacin de un dispositivo cliente virtual sobre una PC, que simule la realizacin de una tarea demostrativa; un dispositivo cliente real que ejecute alguna accin demostrativa real y concreta; y una PC que supervise la red para comprobar su funcionamiento (dispositivo diagnstico); como puede verse el la figura 3.3.

Figura 3.3. Esquema de red recomendable.

FernandoArielBeunza79156

89

Tesis de Grado en Ingeniera Informtica Como el dispositivo cliente virtual y el dispositivo de diagnstico se implementan sobre una PC, se puede concentrar las tareas de los dispositivos anteriores en uno slo para ahorra la construccin de uno de los modems. Tanto para la PC que implemente el dispositivo cliente virtual como para la que supervise la red necesitan interfaces en lenguaje C/C++ para poder construir aplicaciones que simulen un dispositivo cliente y permitan visualizar el funcionamiento de la red respectivamente. Adems las mencionadas interfaces van a permitir la construccin de un biblioteca de bloques Simulink que permitan construir aplicaciones de prueba mediante modelos grficos. Para los dispositivos clientes reales, dado que stos necesariamente deben contener un microcontrolador para acceder al sistema, tambin necesitan una versin de la interfaz anterior para simplificar el acceso al sistema de intercambio de informacin.

90

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

4. Solucin propuesta
La solucin que se propone en el presente trabajo se compone de siete capas conforme al modelo planteado por OSI. sta idea se basa en la forma de implementacin de LonWorks, que tambin implementa las siete capas, y define desde los aspectos fsicos (capa fsica) hasta la interfaz con los dispositivos usuarios de ste (capa de aplicacin). Aqu se intenta integrar las diversas ideas propuestas por los antecedentes estudiados e integrarlas conformando cada una de las capas. Las siete capas no se implementan en un slo microcontrolador, ya que se pretende no involucrar las funciones propias del dispositivo cliente con las funciones relacionadas con las comunicaciones PLC. De ste modo se provee un sistema de comunicaciones lo ms independiente posible de la utilidad que se le de a ste, ya que la separacin absoluta no es posible, debido a que las dos ltimas capas (capas de presentacin y aplicacin) se encuentran muy vinculadas con la plataforma que emplea la implementacin del dispositivo cliente. Las restantes capas se implementan dentro del modem PLC, aunque ste se compone de dos microcontroladores: uno destinado exclusivamente a la capa fsica, y el resto a las capas de enlace, red, transporte y sesin

4.1. Capa fsica


Debido a la imposibilidad de tener acceso a modems PLC, y a que stos ltimos son necesarios para evaluar la propuestas del presente trabajo, se requiere la construccin de un hardware prototipo. El grado de complejidad del hardware en cuestin no podr exceder la disponibilidad de los componentes electrnicos disponibles en el mercado Argentino.

4.1.1. Mtodo de acoplamiento


Como se mencion con anterioridad, en el trabajo Optimization of the Data Transmissions over DC Power Lines [Trnka06-2], se implementa una variante del acoplamiento capacitivo compuesto por dos capacitores en serie a la salida del transmisor. Otra variante del acoplamiento capacitivo es la utilizada en redes LIN sobre PLC [BenziFacchinettiCaprini08] (figura 4.1), que consiste en colocar filtros de rechazo de banda a la salida de la batera y a la entrada de los dispositivo que consumen la energa proporcionada por la batera. De esta forma se bloquea el paso de la seal con informacin a los puntos de la red con baja impedancia, solucionando el problema de la baja impedancia del mtodo capacitivo. El transmisor se acopla a la red por medio de un capacitor y una resistencia conectados en serie, y el receptor emplea un inductor, un capacitor y una resistencia. Los capacitores son necesarios para el bloqueo de la seal continua de potencia, todos los elementos mencionados anteriormente junto con la red cableada conforman un filtro pasa banda.

FernandoArielBeunza79156

91

Tesis de Grado en Ingeniera Informtica

Figura 4.1. Esquema de acoplamiento utilizado en redes LIN sobre PLC.

Para el caso del modem propuesto en el presente trabajo, a partir de las ideas anteriores, se propone un mtodo basado en el acoplamiento capacitivo. La idea bsica de ste mtodo es combinar la simpleza del mtodo de acoplamiento capacitivo con el esquema de filtrado, de forma tal que el conjunto completo constituya un filtro pasa alto que solamente permita el paso de las frecuencias de 4 MHz en adelante. Los conjuntos capacitor resistencia (ver figura 4.1) constituyen un circuito de bloqueo de componente continua y un limitador de corriente, para limitar el consumo de potencia del transmisor y del receptor. Los inductores cumplen la funcin de bloqueo de la seal de informacin evitando que dicha seal no sea afectada por la baja impedancia de la batera y dispositivos de carga considerable.

Figura 4.2. Esquema de acoplamiento a la red PLC propuesto.

El filtro pasa alto conformado por los elementos pasivos de la figura 4.2, no se caracteriza por su selectividad ni tampoco es su principal objetivo, slo se limita a bloquear las frecuencias que ste debajo de la banda de HF no utilizadas para las comunicaciones PLC en automviles. Por sta razn, el receptor necesariamente debe contener un filtro ms selectivo que se concentre en dejar pasar solamente la banda de frecuencias de inters. sto ltimo permite utilizar solamente una 92 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica porcin del espectro destinado para las comunicaciones PLC, dejando libre el resto, para convivencia con futuras aplicaciones basadas en ste tipo de comunicaciones sin necesidad de modificar el esquema propuesto en la figura 4.2.

4.1.2. Tcnica de modulacin


Debido a las caractersticas del canal de comunicaciones, la tcnica de modulacin ms adecuada para transmitir la informacin no debe basarse en la amplitud (quedando descartada ASK y QAM). Debido al desvanecimiento intermitente y selectivo de frecuencias, no puede emplearse una tcnica de modulacin que utilice una sola portadora (ASK y variantes de PSK). Tampoco sera adecuado el empleo de FSK debido a que se utiliza una frecuencia para representar cada smbolo que se desea transmitir (BFSK utiliza una frecuencia para representar el cero y otra para representar el uno), y en caso de desvanecimiento de una de las frecuencias utilizadas se perdera el smbolo correspondiente a dicha frecuencia. Por lo cual puede concluirse que se requiere de una tcnica de modulacin que utiliza mltiples portadoras para transmitir un smbolo, como por ejemplo OFDM. El empleo de OFDM requiere de gran complejidad del transmisor y el receptor que imposibilitara la implementacin del modem PLC con los componentes disponibles en el mercado Argentino. Buscando un equilibrio entre confiabilidad y baja complejidad, se recurre a la tcnica de modulacin DBPSK Adaptada [Trnka06-1] [Trnka06-2]. ste mtodo se basa en la tcnica DBPSK, pero en lugar de emplear una sola portadora, emplea un conjunto de portadoras, lo que hace que ste mtodo junte las ventajas de DBPSK con la resistencia al desvanecimiento provista por la utilizacin de mltiples portadoras. Adems ste mtodo, por derivar de DBPSK, no requiere la implementacin de un recuperador de portadora, lo cual simplifica el receptor.

Figura 4.3. Diagrama de bloques del modem prototipo desarrollado.

En la figura 4.3, se puede observar los bloques bsicos que conforman el modem prototipo desarrollado para el presente trabajo similar al modem DBPSK Adaptado descripto anteriormente. Se conforma de un codificador diferencia integrado por el retardo de un bit y una operacin lgica o-exclusiva en el transmisor encargada de generar los cambios de fase de las portadoras en funcin de los datos a enviar. Las portadoras son sintetizadas por un bloque dedicado para tal fin que genera un nico smbolo que multiplicado por la fase generada por la salida del codificador diferencial conforman la seal con la informacin que viaja a travs del canal de comunicaciones hasta llegar al receptor. En el receptor, la mencionada seal, es retardada un tiempo equivalente a la duracin temporal de un smbolo. La seal recibida y la seal retardada son multiplicadas entre s para poder

FernandoArielBeunza79156

93

Tesis de Grado en Ingeniera Informtica distinguir la fase de cada smbolo recibido que contiene la informacin. Debido a que la seal resultante de la multiplicacin resulta tener cierta cantidad de ruido que no permite distinguir fcilmente el valor de los bits de informacin recibidos, dicha seal es procesada por un bloque integrador que tiene el efecto de filtro pasa bajo resultando una seal que vara de nivel segn el bit de informacin recibido. Por ltimo, un bloque detector se encarga de comparar la seal resultante del integrador contra un valor de referencia utilizado para determinar si el bit de informacin recibido corresponden a un cero o un uno.

4.1.3. Modem PLC


El modem PLC propuesto se basa en el dispositivo descripto en el trabajo, Power Line Communications in Automotive Industry [Trnka05]. Debido a la no disponibilidad de ciertos componentes que integran el modem original, en ste trabajo se implementa una versin diferente realizable con los componentes disponibles en el mercado Argentino. No obstante, el modem propuesto se basa en los mismos principios de funcionamiento del modem original.

Figura 4.4. Diagrama de bloques de un modem PLC prototipo.

Los componentes bsicos del modem PLC prototipo (figura 4.4), se describen a continuacin:

Filtro: consiste en un filtro que rechaza la banda de frecuencias utilizada para transmitir la informacin. Suministra la seal de potencia utilizada para alimentacin libre de ruido. Fuente: proporciona energa a los bloques activos del modem PLC. Transmisor: transmite la informacin por medio de la red de alimentacin utilizando la tcnica de modulacin DBPSK Adaptada, cuya implementacin se describe ms adelante.

94

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Receptor: recibe informacin por medio de la red alimentacin modulada con la tcnica DBPSK Adaptada. La implementacin del receptor se describe ms adelante. Microcontrolador procesador de seales: contiene el software asociado procesamiento de seales. Por sus prestaciones, resulta adecuado la utilizacin del microcontrolador AVR ATmega8515 que permite ejecutar ciertas instrucciones en un ciclo de reloj [ATmega8515]. Microcontrolador de procesamiento: contiene el software asociado al ncleo sistema y el protocolo de enlace. Por sus prestaciones, resulta adecuado la utilizacin del microcontrolador 8052 AT89S52 que permite almacenar el software anteriormente mencionado en una memoria externa ms grande que la provista por el microcontrolador y brinda la posibilidad de expandir la memoria RAM [AT89S52] [AT89CMemOrg]. Memoria: extiende la capacidad de almacenamiento de la memoria RAM del microcontrolador. Para ste caso resulta suficiente que la capacidad de la mencionada memoria sea de 32KB. Esta memoria adicional es necesaria para poder implementar una cola de mensajes. Interfaz RS232: brinda una interfaz con el dispositivo cliente del sistema.

Los detalles sobre la implementacin del modem PLC se encuentran en el Apndice A (Implementacin del hardware del modem PLC), en donde se describen los componentes que constituyen el modem PLC con ms precisin.

4.1.4. Implementacin del sistema de comunicaciones


Tanto el proceso de transmisin como de recepcin se componen de dos partes fundamentales: la parte fsica implementada con circuitos dedicados y la parte lgica constituida por algoritmos ejecutados por el microcontrolador procesador de seales. Esta implementacin permite simplificar los circuitos dedicados y mejorar el procesamiento de las seales involucradas en el proceso de comunicacin.

4.1.4.1. Implementacin fsica


Como se mencion anteriormente la tcnica de modulacin utilizada es DBPSK Adaptada por su posibilidad de ser implementada con la tecnologa de componentes disponible y su inmunidad ante los problemas que presenta el canal de comunicaciones utilizado para las redes PLC. La adopcin de este sistema de modulacin implica una velocidad de transmisin de datos constante (por derivar DBPSK) [Tropeano03], y la necesidad de implementar un sintetizador de portadoras. sta ltima cuestin es la ms problemtica dado que resulta dificultoso sintetizar frecuencia del rango de HF en forma directa. La solucin adoptada fue la sntesis de frecuencias bajas y su posterior conversin [AlleyAtwood68] a un rango de frecuencias de HF. Esta solucin permite que un microcontrolador, que emite una instruccin por ciclo de reloj, pueda sintetizar frecuencias que van desde los 0 hz hasta la cuarta parte de la frecuencia de reloj sin mayores inconvenientes. FernandoArielBeunza79156 95

Tesis de Grado en Ingeniera Informtica El transmisor se compone de un sintetizador de portadoras, implementado por firmware del microcontrolador (ver Implementacin lgica), encargado de generar los smbolos utilizados para transmitir los bits de informacin, que alimentan el conversor digital analgico. La seal resultante es amplificada y filtrada, y a partir de ella se generan dos seales desfasadas entre s por un ngulo de 180, debido a que la conversin de frecuencias se realiza por medio de un modulador VSB-SC (banda lateral vestigial con portadora suprimida), que requiere la seal de informacin con ngulos de desfasaje 0 y 180. La razn de la utilizacin de ste tipo de modulador es el ahorro de energa por no transmitir la portadora (la frecuencia de traslacin) y que el nmero de componentes en frecuencia de la seal smbolo se duplican por tratarse de una tcnica de modulacin de doble banda lateral (mayor cantidad de componentes en frecuencia se corresponde con una mayor redundancia y mayor confiabilidad). La seal resultante se encuentra en el rango de frecuencias de HF, y sta ingresa al amplificador de salida encargado de alimentar al circuito de acoplamiento encargado de propagar la seal a lo largo de la red de potencia. En el Apndice B (Simulacin del hardware del modem PLC) se especifica en detalle los componentes del transmisor mencionados anteriormente, en donde el sintetizador de portadoras se encuentra implementado por un circuito especial que simula al microcontrolador, y la seal resultante puede verse en la parte de dicho apndice donde se muestran los resultados de la simulacin. El receptor se encarga de realizar los pasos en sentido inverso del transmisor. La seal que viaja por medio de la red de potencia llega al circuito de desacoplamiento en donde se filtra la componente contina, quedando solamente la seal con la informacin que alimenta al amplificador de entrada. Dicho amplificador se encarga de amplificar y filtrar de forma ms selectiva la seal con la informacin para el posterior proceso de conversin de frecuencias. El convertidor de frecuencias (demodulador VSB-SC) se encarga de convertir las componentes en frecuencia de HF de la seal con la informacin a componentes en frecuencia manejables por el microcontrolador. La seal resultante de la conversin se digitaliza por medio de un ADC de un bit [Trnka06-2], debido a que el ruido introducido por ste tipo de conversor no afecta significativamente el proceso de demodulacin y ste resulta ms simple de implementar. Debido a que la seal se digitaliza con un bit, se pueden formar grupos de 8 bits, para que el microcontrolador los lea en paralelo y almacene en registros internos, permitiendo la implementacin de una lnea de retardo 80 bits (el smbolo se compone de 80 muestras) con la utilizacin de 10 registros internos (de 8 bits cada uno). Con la seal obtenida leda directamente y la resultante de la lnea de retardo se aplica la operacin lgica o-exclusiva (que ms se asemeja a la multiplicacin de seales), obtenindose una nueva seal digital que se caracteriza por tener ciclos de 80 muestras con muchos ceros (asociados a un bit de informacin de valor uno) o con muchos unos (asociados a un bit de informacin de valor cero). El mecanismo de cuantificar dichos ceros y unos, se realiza por medio de una fuente de corriente, controlada por los bits resultantes de la operacin o-exclusiva, que carga un capacitor; implementado de sta forma un integrador. La seal resultante del integrador es comparada contra un umbral de referencia (determinado por el microcontrolador), para determinar el valor del bit de informacin recibido. En el Apndice B (Simulacin del hardware del modem PLC) se especifica en detalle los componentes del receptor mencionados anteriormente. El microcontrolador se encuentra simulado por un circuito especial que realiza el procesamiento de las muestras de forma similar a como lo hara el correspondiente algoritmo. Las seales involucradas en el proceso de recepcin y la informacin recuperada puede verse en la parte de dicho apndice donde se muestran los resultados de la simulacin.

96

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Figura 4.5. Diagrama de bloques del transmisor y receptor de un modem PLC prototipo.

En el modem PLC propuesto, se utiliza como microcontrolador procesador de seales el AVR ATmega8515 con una frecuencia de reloj de 11,0592 MHz, lo que permite sintetizar frecuencias del rango 0 a 2,7648 MHz. Los convertidores de frecuencia operan con un oscilador de 16 MHz lo que permite trasladar las frecuencias sintetizadas al rango comprendido entre 13,2352 y 15,86176 MHz. Dicho rango de frecuencias resulta adecuado segn el anlisis realizado previamente sobre las caractersticas del canal de comunicaciones.

4.1.4.2. Implementacin lgica


Como se observa en la figura 4.5, ciertos componentes del transmisor y receptor no se implementan con circuitos dedicados sino que se utiliza un microcontrolador dedicado para realizar la sntesis de la seal y la decodificacin de la misma. La ventaja de optar por sta alternativa es la simplificacin de los circuitos del modem PLC. Los bloques sealados en la figura mencionada corresponden a los algoritmos de envo y recepcin respectivamente. El algoritmo de envo consiste en recibir una trama de bits con la informacin a enviar, aplicar codificacin diferencial a dicha trama de bits, y generar el smbolo correspondiente por cada bit resultante del proceso de codificacin. Los smbolos utilizados para transmitir dichos bits se encuentra conformado por 80 muestras, cuyos valores para uno de ellos se pueden ver en la tabla 4.2 (el otro smbolo corresponde a la misma seal desfasada en 180), y generan una seal compuesta por 19 portadoras equiespaciadas en frecuencia dentro de los 0 a 2,7648 MHz (tabla 4.3) de la forma especificada en la figura 4.6, cuyo espectro en frecuencia es el detallado en la figura 4.7. Cada una de las portadoras mencionadas presenta una fase inicial (tabla 4.3) predeterminada para obtener la FernandoArielBeunza79156 97

Tesis de Grado en Ingeniera Informtica menor relacin entre pico y promedio de amplitudes (conocido como PAR) del smbolo [Trnka06-2] , lo que permite que las amplitudes se encuentren comprendidas dentro de un rango de valores no muy grande, para que el conversor analgico digital del receptor pueda digitalizar la seal recibida de forma adecuada. Con una frecuencia de operacin del microcontrolador de 11,0592 MHz, la duracin en tiempo del smbolo es de 7,234 microsegundos aproximadamente, lo que implica una velocidad de transferencia de informacin cercana a los 140 Kbps (dado que cada smbolo representa a un bit).
N Seal Cod. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 2 -3 -6 -5 -2 0 0 -1 -1 -1 0 1 2 2 2 0 09 04 01 02 05 07 07 06 06 06 07 08 09 09 09 07 N Seal Cod. 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 -4 -6 -4 -2 -2 -3 0 3 2 -4 -7 -2 5 4 0 -1 03 01 03 05 05 04 07 0A 09 03 00 05 0C 0B 07 06 N Seal Cod. 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 3 5 4 4 4 2 -4 -6 -1 6 6 1 -2 -3 -3 -4 0A 0C 0B 0B 0B 09 03 01 06 0D 0D 08 05 04 04 03 N Seal Cod. 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 3 0 1 -2 -2 3 7 4 -2 -4 0 5 6 4 4 4 04 07 08 05 05 0A 0E 0B 05 03 07 0C 0D 0B 0B 0B N Seal Cod. 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 4 3 0 -3 -2 2 4 2 -3 -3 2 7 6 6 6 6 0B 0A 07 04 05 09 0B 09 04 04 09 0E 0D 0D 0D 0D

Tabla 4.1. Valores de las muestras del smbolo.


Portadora 1 2 3 4 5 6 7 Frecuencia 138,237 KHz 276,474 KHz 414,711 KHz 552,947 KHz 691,184 KHz 829,421 KHz 967,658 KHz Portadora 8 9 10 11 12 13 14 Frecuencia 1105,895 KHz 1244,132 KHz 1382,368 KHz 1520,605 KHz 1658,842 KHz 1797,079 KHz 1935,316 KHz Portadora 15 16 17 18 19 Frecuencia 2073,553 KHz 2211,789 KHz 2350,026 KHz 2488,263 KHz 2626,500 KHz

Tabla 4.2. Valores de frecuencia de cada portadora del smbolo.


Portadora 1 Fase
180

2
-180

3
0

6
180

7
-180

8
0

9
180

10

11

12
0

13
-180

14
0

15
45

16
135

17
135

18
0

19
180

-180 -180

-135 -180

Tabla 4.3. Valores de fase de cada portadora del smbolo.

98

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Figura 4.6. Grfico de la seal sintetizada correspondiente a un smbolo.

Figura 4.7. Grfico del espectro de la seal sintetizada correspondiente a un smbolo.

El microcontrolador AVR ATmega8515 permite emitir una muestra por ciclo de reloj si stas se encuentran previamente cargadas en registros, ya que la carga a registro de la muestra consume un ciclo de reloj y la emisin de la muestra requiere de otro ciclo de reloj. Debido a que no se disponen de 80 registros para almacenar todas las muestras se sintetiza la seal de tal forma que se repitan frecuentemente los valores de las muestras, lo que permite reducir 80 muestras a un nmero manejable de 15. Adems las muestras son emitidas cuando su valor cambia, por ejemplo, si existen dos o ms muestras consecutivas con el mismo valor, se emite slo una vez la muestra en cuestin ya que el valor de sta queda retenido en el puerto de salida del microcontrolador hasta que sea modificado nuevamente. sto ltimo permite que el microcontrolador pueda realizar otras tareas hasta tanto no sea necesario modificar el valor de la muestras. Una de stas tareas es el cambio de fase del smbolo segn la codificacin diferencial del bit de informacin a enviar. La codificacin diferencial consiste en generar una nueva seal a partir de los cambios de estado que sufre la seal con la informacin, y suponiendo que la duracin de cada estado es constante, no es necesaria la introduccin de una seal de sincronismo para poder recuperar la informacin. En cambio si es necesario un codificador en el transmisor y un decodificador en el receptor que son simples de implementar ya que su lgica es la siguiente: codificador: c(t)=not(c(t1)xors(t))

decodificador: s(t)=not(c(t)xorc(t1))
Figura 4.8. Expresiones lgicas del codificador y decodificador diferencial.

La expresin lgica correspondiente al codificador se implementa dentro del algoritmo sintetizador de seal y el clculo se lleva a cabo en forma paralela a la emisin de las muestras del smbolo (se aprovecha los instantes de no variacin del valor de la muestra en los que no se debe modificar el estado del puerto de salida, y en lugar de introducir una espera, se realiza el clculo). La secuencia de instrucciones encargadas de la sntesis de la seal pueden verse en detalle en el Apndice C (Cdigo fuente), ms especficamente en la implementacin de la parte de la capa fsica perteneciente al firmware procesador de seales, en la rutina dedicada al envo de trama de bits. FernandoArielBeunza79156 99

Tesis de Grado en Ingeniera Informtica La expresin lgica correspondiente al decodificador se implementa dentro de algoritmo de recepcin. Por ejemplo dada una seal de informacin representada por los siguientes 4 bits 1001, suponiendo que el estado inicial es uno, el resultado de la codificacin diferencial sera 1011, y la fase de los smbolos respondera a sta ltima secuencia (siendo uno la fase 0 y cero la fase 180). El decodificador diferencial se compone de una lnea de retardo (implementada con los registros internos del microcontrolador) y un multiplicador de seal (implementado con la operacin oexclusiva provista por el microcontrolador) que multiplica la seal recibida y la misma seal retarda el mismo tiempo de duracin de un smbolo. El resultado final es una seal que pasada por un integrador (implementado de forma fsica) y luego por un detector de nivel devuelve la informacin original 1001. La implementacin de lo anteriormente descripto se encuentra detallada en el Apndice C (Cdigo fuente), ms especficamente en la implementacin de la parte de la capa fsica perteneciente al firmware procesador de seales, en la rutina dedicada a la captura de seal.

Figura 4.9. Diagrama de flujo correspondiente al algoritmo de envo.

100

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Figura 4.10. Diagrama de flujo correspondiente al algoritmo de recepcin.

En las figuras 4.9 y 4.10 se muestran los diagramas de flujo correspondientes a los algoritmos de envo y recepcin, respectivamente. En dichos diagramas se hace mencin al operaciones principales que involucran cada uno de los algoritmos. Todas las operaciones relacionadas a la emisin de muestras y recepcin de las mismas, se realizan en tiempo real, lo que implican que no pueden ser interrumpidas por ningn otra operacin pendiente. Las operaciones que no requieran ser realizadas en tiempo real se realizan antes o despus del bloque de operaciones que requieren ser ejecutadas en tiempo real.

FernandoArielBeunza79156

101

Tesis de Grado en Ingeniera Informtica

4.1.5. Estructura de tramas


La informacin se enva por medio de tramas compuestas de dos secuencias delimitadoras (una de comienzo y otra fin), y entre dichas secuencias se encuentra la informacin. La cantidad de informacin que puede contener una trama esta limitada por la memoria que dispone el mdulo de procesamiento de seales que permite un mximo de 400 bytes. El receptor comienza a almacenar la informacin recibida en su memoria luego de detectar el delimitador de inicio y almacena la cantidad de bytes que le indica la capa inmediata superior, ya que la estructura de la trama no posee ningn campo que contenga el tamao de la trama. El manejo del tamao de la trama, entre otras cuestiones, se delega a la capa superior quien es la que determina el tamao de la trama esperada por el receptor. El delimitador de fin se utiliza para espaciar las tramas. A continuacin se muestra en la figura 4.11 la estructura de la trama descripta:
Delimitador de inicio 128 bits 16 bytes Datos 3200 bits 400 bytes Delimitador de fin 16 bits 2 bytes

Figura 4.11. Estructura de una trama.

Delimitador de inicio: secuencia de bits 128 bits utilizada para marcar el inicio de la trama. La secuencia se compone de tres partes, una primera parte encargada de marcar la ocupacin del canal de comunicacin (16 bits de valor uno, seguido de 1 bit de valor cero, seguido de 23 bits de valor uno), una segunda parte utilizada por el receptor para ajustar su umbral de deteccin (secuencia 01 repetida 32 veces), y por ltimo una secuencia indicadora de comienzo del mensaje (secuencia de 16 bits con valor uno seguida de la secuencia 11011011). Datos: informacin transportada. La mxima capacidad de transporte son 400 bytes. Delimitador de fin: secuencia de 16 bits de valor uno utilizada para marcar el fin de la trama.

4.1.6. Funciones adicionales


Adems de las funciones principales que cumple la capa fsica, que son el envo y recepcin de tramas, existen otras funciones auxiliares que requiere la capa inmediata superior, ms especficamente la subcapa de control de acceso al medio. Una de stas funciones auxiliares es la generacin de ruido, utilizado para indicar la ocupacin de canal. El ruido se compone de una secuencia de bits pseudoaleatorios transmitidos de igual forma que una trama. sta funcin permite a la subcapa de control de acceso al medio indicar la ocupacin del canal de comunicaciones. La anterior funcin se encuentra asociado con la funcin de escucha del canal de comunicaciones. sta funcin se encarga de escuchar la actividad presente en el canal durante un tiempo especificado, y reportar cuando se sobrepasa un determinado umbral de energa. sta funcin es empleada por la subcapa de control de acceso al medio para determinar la ocupacin o no del canal de comunicaciones, siendo la subcapa de control de acceso al medio quien determina el tiempo de escucha, y el umbral que se debe sobrepasar para considerar el canal ocupado. 102 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica Las anteriores funciones brindan soporte a la subcapa de control de acceso al medio para que sta pueda implementar el algoritmo que controla el acceso al medio, y el mecanismo de confirmacin de recepcin. Adems de las funciones descriptas hasta el momento, existen otras orientadas a la realizacin de pruebas de funcionamiento, y para evaluacin de los componentes del hardware descripta en el captulo 5. Las funciones permiten la generacin de seales de prueba utilizadas verificar el correcto funcionamiento del hardware y evaluar la respuesta en frecuencia del mismo.

4.1.7. Primitivas de manejo de la capa fsica


Como se mencion anteriormente, ciertos componentes del transmisor y receptor no se implementan fsicamente con circuitos dedicados, sino que se utiliza un microcontrolador dedicado exclusivamente al procesamiento de seales. Tambin se hizo mencin a que esta forma de implementacin tiene la ventaja de simplificar los componentes fsicos del modem PLC, pero dicha simplificacin trae como consecuencia la creacin de un firmware adicional de procesamiento de seales para resolver las cuestiones no resueltas por los componentes fsicos. Adems es necesario implementar firmware adicional que permita la comunicacin entre el microcontrolador dedicado al procesamiento de seales y el microcontrolador dedicado al procesamiento de mensajes. Debido a que se ha optado como norma para la realizacin de ste trabajo el respetar el modelo OSI de capas independientes entre s, es necesario implementar un conjunto de primitivas que brinden una abstraccin hacia las capas superiores del manejo de los aspectos fsicos que involucran en proceso de comunicacin (comunicacin entre los microcontroladores mencionados anteriormente, sntesis de seales, decodificacin de las mismas, etc.). De esta forma se deja abierta la posibilidad de futuras actualizaciones de la capa fsica, sin que stas alteren la implementacin de las restantes capa superiores. A continuacin se detallan las primitivas referentes al manejo de la capa fsica (cuya implementacin se detalla en el Apndice C, especificacin del cdigo fuente del firmware del modem PLC) que permiten manejar al procesador de seales desde el microcontrolador dedicado al procesamiento de mensajes, proporcionando las funcionalidades de inicializacin y liberacin de recursos (activacin y desactivacin del transmisor y/o receptor), envo de tramas y recepcin de los mismas, y otras funcionalidades ms especificas referentes al hardware:

void phy_init(void): Inicializa los recursos que comprenden todo el proceso de comunicacin por medio de la red de potencia. Inicializa el buffer de mensajes, inicializa la interrupcin de recepcin de mensajes y pone en funcionamiento al circuito receptor. void phy_release(void): Libera los recursos que comprenden todo el proceso de comunicacin por medio de la red de potencia inicializados por la primitiva anterior. short int phy_sndframe(const void *dat, short int size): Enva una trama dat de longitud size. Esta primitiva tiene la responsabilidad de generar, a partir de la anterior trama, la seal con la informacin que es transmitida por la red de potencia. Implementa el algoritmo de envo detallado en la figura 4.9. Devuelve como resultado la cantidad de bytes enviados, que coincide con size si la operacin de envo pudo ser realizada.

FernandoArielBeunza79156

103

Tesis de Grado en Ingeniera Informtica

int phy_capframe(short int size): Inicia la captura de una trama de longitud size. Esta primitiva se encarga de poner al mdulo de procesamiento de seales en espera de una trama. Dicho mdulo comenzar a almacenar la trama recibida al momento que detecte el patrn de bits preestablecido por el mdulo de procesamiento de seales. La captura finaliza cuando se lee la cantidad de bytes especificados por el parmetro size. Mientras no se detecte la llegada del patrn de bits preestablecido, el mdulo de procesamiento de seales se encuentra en espera, que puede ser interrumpida por cualquier otra operacin. Esta primitiva implementa el algoritmo detallado en la figura 4.10. En caso de haberse podido dar inicio a la captura devuelve como resultado un valor positivo distinto a cero. short int phy_getframe(void *dat, short int size): Lee size bytes del contenido del buffer del mdulo de procesamiento de seales y lo almacena en dat. En caso de haberse ejecutado la primitiva anterior, y haber llegado una trama, el buffer contendr mencionada trama. En caso de haberse ejecutado la primitiva de envo de trama, el buffer contendr la trama enviada. El contenido de buffer podr leerse de forma repetida obteniendo la misma informacin hasta que no sea limpiado, por la correspondiente primitiva, o modificado por el envo o la captura de una nueva trama. Como resultado devuelve la cantidad de bytes ledos del buffer. void phy_notify(void (*func)(void)): Esta primitiva brinda la posibilidad de definir una funcin func que se ejecute cuando se haya capturado una trama. El objetivo de sta primitiva es evitar la espera de la llegada de una trama, realizando permanentemente consultas y consumiendo recursos del microcontrolador. int phy_poll(void): Esta primitiva verifica si se ha capturado una trama. Devuelve como resultado uno si el buffer contiene una trama capturada a la espera de ser leda mediante la primitiva phy_getframe. Si no se ha capturado ninguna trama el resultado devuelto es cero. Con esta primitiva se puede implementar una espera de la llegada de una trama, en circunstancias en las cuales no sea conveniente utilizar la primitiva anterior. int phy_rsdsignal(void): Esta primitiva se similar a phy_sndframe, pero no es necesario especificar la trama a enviar, ya que repite el ltimo envo realizado. sto permite implementar de forma ms eficiente la repeticin de envos evitando la transferencia de la trama hacia el mdulo de procesamiento de seales. Tambin puede utilizarse para reenviar una trama capturada mediante la primitiva phy_capframe. En caso de haberse podido realizar el reenvo devuelve como resultado un valor positivo distinto a cero. int phy_clrbuffer(void): Esta primitiva permite limpiar el contenido del buffer del mdulo de procesamiento de seales. En caso de haberse podido realizar dicha operacin devuelve como resultado un valor positivo distinto a cero. int phy_sensechannel(unsigned char thrl, long int usecs): Esta primitiva permite sensar el estado del canal de comunicaciones durante un tiempo de usecs microsegundos. Mientras no se detecte ocupacin del canal de comunicaciones, el FernandoArielBeunza79156

104

Tesis de Grado en Ingeniera Informtica mdulo de procesamiento de seales, se encuentra a la espera (durante el tiempo establecido) de una seal que ocupe dicho canal cuya energa alcance el nivel de umbral establecido por thrl. En caso que se alcance dicho nivel de umbral, se interrumpe la espera y devuelve como resultado un valor positivo distinto a cero. Una vez transcurrido el tiempo de espera, devuelve como resultado el valor cero.

int phy_gennoisesignal(void): Esta primitiva permite generar una seal de ruido que ocupe el canal de comunicaciones. Dicha seal de ruido se genera a partir de una secuencia pseudoaleatoria de bits modulados en BPSK. La generacin de la seal de ruido puede ser interrumpida en cualquier momento por la ejecucin de cualquier otra primitiva. En caso de haberse podido dar comienzo a dicha operacin devuelve como resultado un valor positivo distinto a cero. int phy_tstsignal1(void): Esta primitiva permite generar una seal de prueba. La seal es una onda senoidal de 138,237 KHz, utilizada solamente para realizar pruebas de hardware. La generacin de dicha seal puede ser interrumpida por la ejecucin de cualquier otra operacin. En caso de haberse podido dar inicio a la generacin de la seal de prueba devuelve como resultado un valor positivo distinto a cero. int phy_tstsignal2(void): Esta primitiva permite generar una seal de prueba. La seal es una onda senoidal de 552,947 KHz, utilizada solamente para realizar pruebas de hardware. La generacin de dicha seal puede ser interrumpida por la ejecucin de cualquier otra operacin. En caso de haberse podido dar inicio a la generacin de la seal de prueba devuelve como resultado un valor positivo distinto a cero. int phy_tstreceive(void): Esta primitiva permite verificar la recepcin de seales por parte del receptor. La prueba de recepcin puede ser interrumpida por la ejecucin de cualquier otra operacin. En caso de haberse podido dar inicio a la generacin de la seal de prueba devuelve como resultado un valor positivo distinto a cero.

El conjunto de primitivas descripto abstrae en dos primitivas la inicializacin y liberacin de los recursos utilizados por la capa fsica, en siete primitivas el envo, recepcin y manipulacin de tramas por medio de una red de potencia, en dos primitivas de manipulacin del canal de comunicacin, y en tres primitivas de prueba. Las tramas recibidas son bytes en bruto los cuales no presentan ningn tipo de control de error ni ninguna identificacin del dispositivo originario y destinatario. Es responsabilidad de la capa superior (enlace) el resolver stas ltimas cuestiones.

4.2. Capa de enlace


La capa fsica brinda la posibilidad de transmitir tramas por medio de la red PLC, lo cual no es suficiente para intercomunicar dos o ms dispositivos, ya que se requiere que la informacin fluya por medio de un circuito de transmisin de datos libre de errores. Para lograr sto ltimo, la capa de enlace tiene la responsabilidad de recibir la informacin fragmentada en paquetes,

FernandoArielBeunza79156

105

Tesis de Grado en Ingeniera Informtica conformar tramas a partir de dichos paquetes, gestionar un mecanismo de direccionamiento para dichas tramas, controlar el flujo de la informacin, garantizar que la informacin llegu a destino libre de errores y controlar el acceso al medio fsico utilizado para transmitir las tramas. La implementacin de la capa de enlace se subdivide en dos subcapas: control de acceso al medio (conocida como MAC) y control de lgica de enlace (conocida como LLC).

4.2.1. Subcapa de control de acceso al medio


La subcapa de control de acceso al medio se encarga principalmente de controlar el acceso a un nico medio fsico comn a todos los modems PLC. Otras responsabilidades de esta subcapa son el direccionamiento de los paquetes y controlar que los mismos, cuando lleguen al receptor, no tengan errores.

4.2.1.1. Caractersticas del medio


Todos los modems PLC utilizan como nico medio de comunicacin la red de potencia. La consecuencia de sto ltimo es que dichos dispositivos no pueden transmitir en forma simultnea, por lo cual necesitan de un mecanismo de coordinacin para que todos los dispositivos puedan transmitir sus tramas de informacin en algn momento evitando que haya colisiones de tramas o, por lo menos, si ocurren colisiones exista algn mecanismo de resolucin. Otra caracterstica del medio es que la capa fsica slo brinda un servicio de transmisin de tramas sin ningn tipo de control de errores, lo que significa que existe la posibilidad de recibir tramas con informacin errnea debido a ruido en la red de potencia o interferencia (en el caso de que haya colisiones). Por ltimo, debe observarse, que al tratarse de un nico medio comn, todo lo que sea transmitido a travs de l ser escuchado por todos los dispositivos conectados al medio (broadcast), lo que implica que en los receptores es necesario implementar un mecanismo de filtrado, ya que no todos los dispositivos estn interesados en recibir todas las tramas (mecanismo de direccionamiento). Adems del direccionamiento de los dispositivos, es necesario implementar un mtodo de tratamiento de errores basado en la retransmisin de tramas.

4.2.1.2. Mtodo de acceso al medio


Como se mencion anteriormente, el modem PLC requiere de un mecanismo de control de acceso al nico medio fsico de comunicaciones compartido con otros modems. El medio fsico slo soporta una transmisin a la vez porque slo se dispone de un slo canal y mltiples transmisiones en simultneo corrompen el contenido de las mismas, por lo tanto la nica forma de que todos los modems puedan realizar transmisiones sin interferirse entre s es estableciendo un protocolo de gestin del canal de comunicaciones. En el mbito de redes se han implementado diversos mtodos para resolver sta cuestin del acceso al medio. Existen mtodos que garantizan tiempos de acceso determinsticos, como los que hacen uso de un testigo que es utilizado como un permiso de utilizacin del canal de comunicaciones. Ejemplos de stos son las redes Token Ring y Token Bus [Stallings97], en donde, para el caso de las primeras los dispositivos se interconectan entre s formando un anillo (como sucede en redes como D2B y MOST) por donde circula el testigo, que habilita al dispositivo que lo

106

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica posee a enviar un mensaje que circula por todo el anillo hasta volver al dispositivo que lo origin, quien lo retira de circulacin (en circunstancias de normal funcionamiento). Las redes Token Bus funcionan de modo similar, pero el anillo no es fsico sino que se crea un anillo lgico sobre una red fsica tipo bus. Estos mtodos de acceso al medio mencionados y sus derivados pueden garantizar un tiempo de acceso determinstico porque se puede calcular el tiempo mximo que un dispositivo que entrega el testigo lo vuelve a obtener en funcin a la cantidad de dispositivos presentes en la red. sto ltimo puede funcionar de forma eficiente con redes con pocos dispositivos, pero al aumentar el nmero de dispositivos se eleva el tiempo que tarda el testigo en circular por toda la red lo que puede provocar que las comunicaciones sean muy lentas. Adems el mantenimiento del anillo requiere una lgica compleja ya que la cada de un dispositivo provoca que se rompa el anillo, por lo que deben implementarse mtodos de recuperacin. Algo similar puede ocurrir si se pierde el testigo, porque se perdi la conexin con el dispositivo que lo posea en ese momento. Como los mtodos anteriores tiene como punto dbil la cantidad de dispositivos conectados y el mantenimiento de la estructura lgica de comunicacin, han surgido con xito otros mtodos que garantizan tiempos de acceso probabilsticos independientes de la cantidad de dispositivos de la red, y con una lgica ms simple. El primero de ellos es el CSMA/CD [Stallings97] utilizado en las redes Ethernet que consiste en que un dispositivo que desee transmitir un mensaje, primero debe escuchar el canal y si se encuentra libre puede transmitir, en caso de que otro dispositivo haya hecho algo similar ocurrir una colisin que ser detectada por ambos dispositivos; en tal caso cada uno aplicar un tiempo de espera aleatorio y luego volvern a intentar transmitir. ste proceso puede derivar en varios reintentos de transmisin que sumado a los tiempos de espera aleatorios hacen que no se pueda garantizar un tiempo mximo de demora para transmitir un mensaje (carcter probabilstico), pero ste mtodo de gestionar el medio no necesita de una lgica adicional para mantener un anillo como ocurra en los mtodos de tiempo determinstico. El mtodo CSMA/CD puede funcionar bien para transmisin de datos en general, pero no resulta muy adecuado en aplicaciones de tiempo real en donde se necesita predecir con ms certeza el tiempo que tarda en enviarse un mensaje a lo largo de la red, ms an sin existen muchos dispositivos queriendo transmitir, lo que provoca el aumento de la colisiones. Para mejorar estos inconvenientes han surgido modificaciones a ste mtodo que se centran en resolver las colisiones para evitar la retransmisiones de mensajes que pueden ocasionar ms colisiones. Uno de ellos es el utilizado en redes CAN y J1850 que trabaja con el esquema de bit dominante, en el cual cada mensaje se compone de una cabecera con una secuencia de bits destinada al arbitraje en caso de que se produzca una colisin. Si existen varios dispositivos transmitiendo en forma simultnea, continuar transmitiendo el dispositivo cuya cabecera recibida coincida con la emitida, y los restantes dispositivos detendrn la transmisin. ste mtodo logra establecer un sistema de prioridad de transmisin lo cual permite un tratamiento diferenciado de los mensajes mejorando el comportamiento en aplicaciones de tiempo real. Para el caso particular del modem PLC existen diversos inconvenientes que dificultan o impiden la implementacin de los mtodos anteriores. La implementacin de un mtodo basado en el paso de testigos hara muy compleja la lgica de mantenimiento de un estructura lgica con forma de anillo sobre una red de topologa tipo bus (similar a Token Bus). El mtodo CSMA/CD podra ser una alternativa vlida, pero el modem PLC no puede escuchar el canal mientras transmite un mensaje (problema que tambin presentan los dispositivos que trabajan con DC-BUS), porque resulta muy costosa la implementacin con la tecnologa utilizada en el modem. Tampoco podra implementarse un mtodo similar a CAN ya que no se puede definir un bit dominante, ya que el bit dominante slo puede funcionar en esquemas de transmisin en banda base. Entonces la alternativa surge de un mtodo empleado en redes inalmbricas y en redes HomePlug que deriva del CSMA/CD, conocido como CSMA/CA [Stallings97], en donde si bien la colisiones no se eliminan, se intentan evitar por el problema anteriormente expuesto para detectar FernandoArielBeunza79156 107

Tesis de Grado en Ingeniera Informtica las colisiones. Adems el mtodo CSMA/CA no requiere de escuchar el medio de forma simultnea a la transmisin, sino que se transmite el mensaje y el destinatario del mismo es el encargado de verificar si ste lleg sin errores, y en caso afirmativo le enva la confirmacin de recepcin al transmisor. En caso de existir algn tipo de interferencia por colisin de mensajes o ruido en el medio, el mensaje ser retransmitido luego de un tiempo de espera de duracin aleatoria (similar al utilizado en CSMA/CD). El mtodo CSMA/CA al igual que el CSMA/CD han sido diseados para redes de datos en mbitos en donde las aplicaciones que hacen uso de ellas no son de tiempo real. En el caso particular del presente trabajo se pretende poder determinar el tiempo de envo de un mensaje con alguna certeza. Por esta razn, a lo largo de ste trabajo se irn introduciendo algunas mejoras que apuntes a mejorar sta cuestin. Una de las mejoras que se introduce a este nivel, es la implementacin de un sistema de prioridades para los mensajes. Dichas prioridades influyen en el tiempo de espera entre las escuchas de canal (figura 4.12), haciendo que el nmero de prioridad sea proporcional al tiempo de espera. Esto significa que un nmero bajo implica una espera corta y un nmero alto una espera larga, haciendo que el nmero bajo signifique alta prioridad y un nmero alto menos prioridad, debido a que el menor tiempo de espera implica ms oportunidades de ganar el uso del canal para transmitir el mensaje.

Figura 4.12. Diagrama de flujo correspondiente al mtodo CSMA/CA.

108

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica El algoritmo de la figura 4.12 muestra las acciones involucradas en el envo de una trama. Como se puede ver, cada vez que una trama no es recibida de forma correcta, sta debe retransmitirse con un cierto costo de tiempo. Por las caractersticas del canal de comunicaciones utilizado sto puede resultar frecuente, por lo cual no es recomendable enviar mucha informacin en una trama, porque con slo un bit errado, se pierde toda la informacin contenida en la trama. Para minimizar las prdidas de informacin, y disminuir el tiempo insumido por retransmisiones, se hace necesario la implementacin de un esquema de fragmentacin a nivel de la subcapa de control de acceso al medio.

4.2.1.3. Fragmentacin
La finalidad de implementar un esquema de fragmentacin a nivel de subcapa de control de acceso al medio principalmente es la de hacer un uso ms eficiente de un medio en donde las tramas enviadas con frecuencia son destruidas por cambios en el valor de algunos bits. Adems en este caso particular, la fragmentacin se utiliza para extender la capacidad de envo de informacin con respecto al lmite impuesto para la capa inferior. Como ya se trat anteriormente, cuando se habl sobre el medio sobre el cual se est trabajando, el medio es ruidoso lo que provoca, a pesar de la tcnicas de modulacin implementadas a nivel de capa fsica, la ocurrencia de errores ocasionan la destruccin de la trama, lo que lleva a reiteradas retransmisiones de la misma hasta que su recepcin sea correcta. Para el caso de tramas de pocos bytes, la demora ocasionada por las sucesivas retransmisiones no resulta demasiada; lo que no se puede decir en el caso de tratar de las tramas que ronden el tamao mximo, en el cual el cambio de un slo valor de un bit puede destruir la trama completa de 3200 bits (tamao mximo permitido por la capa inferior). Debido a que reiteradas transmisiones de una trama de tantos bits puede insumir demasiado tiempo de espera, se hace necesaria la implementacin de un esquema de fragmentacin para que toda la informacin que se enva, se haga en varias tramas, que en caso de destruirse una de ellas, solamente sea necesaria la retransmisin de un parte de la informacin original, demorando menos tiempo la recepcin completa del mensaje. El algoritmo de envo para una trama corta corresponde al de la figura 4.12, mientras que para una trama larga se emplea una variante del anterior en donde se enva previamente un pedido de envo de trama (con el tamao de la trama a enviar), utilizando el algoritmo de la figura 4.12 y cuando se tiene la confirmacin de recepcin, se comienzan a transmitir los sucesivos fragmentos sin esperas aleatorias de por medio. Cada fragmento enviado debe esperar la confirmacin de recepcin para poder enviar el siguiente fragmento. En el caso de no recibirse confirmacin, el tamao del fragmento se disminuye a la mitad de tamao y se vuelve a intentar la transmisin del mismo, hasta alcanzar el tamao mnimo permitido de mensaje, en cuyo caso se continua reenviando el mismo fragmento hasta agotar el lmite de reenvos en cuyo caso el algoritmo termina devolviendo error de transmisin. En la figura 4.13 se muestra el diagrama de flujo correspondiente al algoritmo empleado para el envo de tramas largas.

FernandoArielBeunza79156

109

Tesis de Grado en Ingeniera Informtica

Figura 4.13. Diagrama de flujo correspondiente al algoritmo de envo de tramas largas.

La fragmentacin excesiva tambin puede ser perjudicial, ya que resulta en una mayor demora debido a que la cantidad de informacin de control de cada fragmento puede ser significativa en comparacin a la informacin que se pretende enviar. El esquema propuesto siempre comienza intentando enviar la mayor cantidad posible de informacin en cada trama para minimizar la cantidad de tramas. Igualmente se establece que los fragmentos no pueden tener menor longitud que la que posee una trama corta. Para la solucin propuesta en ste trabajo, se considera

110

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica que la longitud de una trama corta no puede superar el doble de la cantidad de bytes utilizados para informacin de control de una trama (en este caso resulta 26 bytes * 2 = 52 bytes, ver figura 4.14).

4.2.1.4. Esquema de direccionamiento


Como se hizo mencin anteriormente, es necesario poder identificar a cada uno de los modems PLC conectados a la red de potencia, para poder dar soporte a comunicaciones punto a punto. Para ello no es suficiente con que modem PLC cuente con una direccin identificatoria cualquiera, sino que sta debe ser nica, ya que si existieran dos dispositivos con la misma direccin, establecer una comunicacin punto a punto sera imposible. Para garantizar sto ltimo se opta por utilizar en los modems PLC un mecanismo de direccionamiento similar al utilizado en las placas de red Ethernet que consiste en asignar a cada dispositivo una direccin nica e irrepetible compuesta en este caso por 8 bytes (64 bits). Dicha direccin es asignada por el fabricante y no puede ser modificada por el usuario, garantizando de sta forma que la direccin sea nica. De esta forma, la subcapa de control de acceso al medio puede brindar un servicio de filtrado de tramas por direccin destinataria y un servicio de transmisin de informacin punto a punto. Pero tambin puede requerirse otros tipos de transmisin como un broadcast, en donde un dispositivo enve una trama de informacin a todos los dems sin necesidad de conocer todas las direcciones destinatarias. Para ello se reserva la direccin FF:FF:FF:FF:FF:FF:FF:FF (64 bits con valor 1) para broadcast, lo que significa que cualquier dispositivo que reciba un paquete con sta direccin destinataria lo debe aceptar como si fuera la direccin propia del dispositivo.

4.2.1.5. Estructura de tramas


Las tramas, adems de contener la informacin a enviar, poseen cierta informacin adicional de control necesaria para que el dispositivo destinatario pueda desarmarlos y recuperar la informacin originalmente enviada. De los 400 bytes de capacidad mxima provistos por la capa inferior, se destinan 374 bytes para datos y el resto para informacin de control. No solamente deben existir paquetes que transporten informacin, sino que son necesarias tramas dedicadas exclusivamente a enviar informacin de control para coordinacin entre el transmisor y el receptor. Para el caso particular de la presente subcapa se requiere de una trama de peticin de envo de trama para poder enviar informacin en varios fragmentos. Por lo tanto, para sta subcapa se define una nica estructura de trama que permite transportar informacin y peticin de recepcin, detallada a continuacin en la figura 4.14:
Delimitador Direccin de destino Direccin de origen Tipo de paquete Protocolo Fragmento Tamao de fragmento Tamao total Datos Cdigo detector de errores

8 bits 1 byte

64 bits 8 bytes

64 bits 8 bytes

8 bits 1 byte

8 bits 1 byte

8 bits 1 byte

16 bits 2 byte

16 bits 2 byte

2992 bits 374 bytes

16 bits 2 bytes

Figura 4.14. Estructura de una trama.

Delimitador: secuencia de bits 01111110 utilizada para marcar el comienzo de la trama. Dado que una secuencia de bytes recibida de la capa fsica puede corresponder a una trama o a ruido, se requiere de una primera verificacin simple para evitar la interpretacin de algo que puede no ser una trama vlida. 111

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica Direccin de destino: direccin del modem PLC destinatario del paquete. Si la direccin es FF:FF:FF:FF:FF:FF:FF:FF (64 bits con valor 1), por ser la direccin reservada para broadcast, el paquete es para todos los modems PLC conectados a la red. Direccin de origen: direccin del modem PLC que origin la trama. Esta direccin no puede ser la de broadcast (FF:FF:FF:FF:FF:FF:FF:FF), por carecer de sentido. Tipo de paquete: especifica el tipo de paquete que puede ser de control o de datos. Protocolo: especifica el identificador asociado al paquete. Fragmento: especifica el identificador de fragmento. Tamao de fragmento: especifica el tamao del campo de datos, cuya capacidad mxima es de 374 bytes. Tamao total: especifica la cantidad total de bytes contenida en uno o mas fragmentos. La cantidad mxima es de 1024 bytes. Datos: informacin transportada. La mxima capacidad de transporte son 374 bytes. Cdigo detector de errores: es un CRC de 16 bits calculado a partir de todos los bytes que conforman la trama (excluyendo al cdigo detector de errores).

4.2.1.6. Control de errores


La subcapa de control de acceso al medio posee tres verificaciones para aceptar o descartar las tramas recibidas. El primer control es realiza con el patrn preestablecido al comienzo de la trama, descartando cualquier tipo de trama originada por ruido en la red de potencia o interferencia. La finalidad de ste control es ahorrar todo el costo de interpretacin de la trama, en caso de que la trama fuera originada por ruido. El segundo control se relaciona con el tamao de los datos que transporta la trama ya que es necesario conocerlo para determinar en que posicin se encuentra el campo de cdigo detector de errores. En caso de que el valor del tamao de los datos no sea vlido (mayor a 374 bytes), se descarta la trama por entenderse de que por ruido o interferencia el tamao de los datos tom un valor invlido, por lo cual la trama se encuentra corrompida. La tercer, y ltima, verificacin es la ms importante ya que verifica la validez del contenido de la trama. Excluyendo los 2 bytes finales del paquete (cdigo detector de errores), con el resto de la trama se obtiene un cdigo CRC de 16 bits. ste cdigo debe coincidir con el CRC recibido, que fue calculado de forma similar en el origen. En caso afirmativo se contina con el procesamiento de la trama, caso contrario se descarta. Si una trama ha logrado pasar con xito las verificaciones anteriormente descriptas, y la direccin destinataria corresponde a algn modem PLC o a todos (direccin de broadcast), el o los destinatarios de la trama emiten una respuesta confirmando la correcta recepcin. El sistema de confirmacin de recepcin se basa en parte al utilizado en CAN y J1850, pero como no es posible definir un valor de bit dominante, se recurre tambin a principio utilizado por DC-BUS para la 112 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica resolucin de colisin. Cuando uno o varios dispositivos emiten una confirmacin de recepcin, generan una seal de ruido de ocupacin del canal seguido de un silencio para indicar al transmisor de la trama, y al resto de los dispositivos conectados, que la trama ha sido correctamente recibida. Durante el silencio mencionado, los dispositivos escuchan la actividad del canal, debido a que si alguno de los destinatarios reporta un error de recepcin lo har ocupando el espacio de silencio, y de esta forma el resto de los dispositivos, aunque hayan recibido correctamente la trama, la rechazarn. Este mecanismo descripto, logra garantizar que una trama sea recibida de forma correcta por todos los destinatarios o en su defecto por ninguno, lo que provocar sucesivas retransmisiones de la misma hasta lograr la correcta recepcin. En caso de no existir ningn destinatario, luego de la transmisin de la trama habr silencio en el canal, y el transmisor interpretar este silencio tambin como un error de transmisin. El mecanismo de confirmacin de recepcin descripto es utilizado tanto para tramas pequeas, como para fragmentos de una trama ms grande y para la peticin de envo. La no confirmacin de recepcin de una peticin de envo evita el costo de tiempo de enviar los sucesivos fragmentos con los datos de la trama. Gracias a ste mecanismo se puede ofrecer un servicio de multicast confiable a las capas superiores, de una forma menos compleja que si se lo hiciera a nivel de las capas superiores. La cantidad de transmisiones que han tenido una falla son contabilizadas por el modem PLC, y la cuenta es reiniciada al detectarse una transmisin correcta de una trama (sea una trama pequea individual o todos los fragmentos de una trama mas larga). sta cuenta es independiente a la utilizada para reportar la falla de envo de trama, y es utilizada para desactivar el dispositivo en caso de sobrepasar la cantidad mxima de fallas permitidas. Cuando se desactiva el modem PLC, no se pueden ni enviar ni recibir tramas, dado que se interpreta que por alguna razn el dispositivo no puede comunicarse con el resto, por lo cual se lo fuerza a abandonar al red. La subcapa de control de acceso al medio se limita a detectar esta situacin de falla, desactivar el dispositivo y notificarlo a las capas superiores, para que alguna de estas se encargue de gestionar una posible reconexin a la red.

4.2.1.7. Filtrado de tramas


La subcapa de control de acceso al medio brinda una funcionalidad de filtrado de tramas por medio de un identificador de protocolo. Est funcionalidad es un agregado que permite a la subcapa de control de lgica de enlace implementar el multiplexado de protocolos y el control de flujo para cada protocolo con el cual trabaje. El esquema de filtrado trabaja con una tabla en donde se almacena el estado de cada identificador de protocolo que puede ser bloqueado o no bloqueado. Cada vez que se recibe una trama sin errores se consulta la mencionada tabla y se verifica que el protocolo asociado a la trama recibida no se encuentre bloqueado. Si el protocolo no se encuentra bloqueado, la trama se procesa como correcta enviando la correspondiente confirmacin de recepcin. En caso de que el protocolo se encuentre bloqueado, a pesar de que la trama no presenta errores, se reporta recepcin errnea como si la trama hubiera sido recibida con errores, con el mecanismo descripto con anterioridad. El filtrado adems de asistir a la subcapa de control de lgica de enlace, permite adems la no ocupacin de los recursos de la subcapa de control de acceso al medio en una trama que no ser procesada por la subcapa superior.

FernandoArielBeunza79156

113

Tesis de Grado en Ingeniera Informtica

4.2.1.8. Primitivas de manejo de la subcapa de control de acceso al medio


A continuacin se detallan las primitivas referentes al manejo de la subcapa de control de acceso al medio (cuya implementacin se detalla en el Apndice C) que proporcionan las funcionalidades de inicializacin y liberacin de recursos, envo de mensajes y recepcin de los mismo:

void mac_init(void): Inicializa la capa fsica, el buffer de mensajes y la funcin de recepcin de mensajes. void mac_release(void): Libera los recursos inicializados por la primitiva anterior. short int mac_send(mac_addr dest_addr, unsigned char prio, unsigned char prot, const void *msg, short int msgsize): Enva un paquete de informacin msg de longitud msgsize con prioridad prio asociado al protocolo prot al dispositivo cuya direccin es dest_addr. Devuelve como resultado la cantidad de bytes enviados, que coincide con msgsize si la operacin de envo pudo ser realizada. short int mac_receive(mac_addr addr, unsigned char *prot, void *msg, short int msgsize): Recibe msgsize bytes que se transfieren a msg, de un paquete asociado al protocolo prot proveniente del dispositivo cuya direccin es addr. Cuando se recibe una trama desde la capa fsica, se invoca la funcin dedicada a recepcin y procesamiento de tramas. Si luego de interpretar dicha trama, sta corresponde a un paquete, ste se almacena en un buffer. Esta primitiva transfiere msgsize bytes del contenido del buffer a msg y devuelve la cantidad de bytes transferidos como resultado. Si el buffer se encuentra vaco, queda a la espera de que llegu un paquete. void mac_notify(void (*func)(mac_addr addr, unsigned char prot, void *msg, short int msgsize)): Esta primitiva brinda la posibilidad de definir una funcin func que se ejecute cuando se recibe una trama. Dicha funcin debe tener definidos como parmetros addr, prot, msg y msgsize, que cumplen la misma funcin que en la primitiva de anterior. El objetivo de sta primitiva es poder procesar la informacin que transporta la trama de forma inmediata a la recepcin de la misma, sin bloquear el microcontrolador, como ocurre con la anterior primitiva. int mac_poll(void): Esta primitiva verifica el estado del buffer. Devuelve como resultado uno si el buffer contiene un paquete a la espera de ser recibido mediante la primitiva mac_receive. Si el buffer se encuentra vaco el resultado devuelto es cero. De sta forma puede implementarse una espera no bloqueante utilizando la primitiva mac_receive. int mac_acceptprotocol(unsigned char prot): Esta primitiva permite la recepcin de paquetes asociados al protocolo prot. Devuelve como resultado uno si se pudo establecer el permiso, caso contrario el resultado devuelto es cero. FernandoArielBeunza79156

114

Tesis de Grado en Ingeniera Informtica int mac_rejectprotocol(unsigned char prot): Esta primitiva establece el rechazo de todos los paquetes asociados al protocolo prot. Devuelve como resultado uno si se pudo establecer el rechazo, caso contrario el resultado devuelto es cero. int mac_status(void): Esta primitiva verifica el estado del dispositivo. Devuelve como resultado uno si el dispositivo se encuentra operativo. Si el dispositivo se encuentra inactivo debido a la ocurrencia de fallas el resultado devuelto es cero. int mac_getaddress(mac_addr addr): Esta primitiva devuelve la direccin fsica asignada al dispositivo.

El conjunto de primitivas descripto abstrae en dos primitivas la inicializacin y liberacin de los recursos utilizados por la subcapa de control de acceso al medio, en seis primitivas el envo y recepcin (en modo bloqueante y no bloqueante) de paquetes, y en dos primitivas la obtencin de informacin acerca del dispositivo. Los paquetes recibidos son los que tiene direccin destinataria la del receptor o la direccin de broadcast. Adems se controla que los paquetes no contengan errores, aunque dicho control no es infalible y requiere de otro control de errores proporcionado por la subcapa superior de lgica de control de enlace.

4.2.2. Subcapa de control de lgica de enlace


La subcapa de control de lgica de enlace (subcapa LLC) se encarga de multiplexar diversos protocolos sobre la subcapa de control de acceso al medio (subcapa MAC), controlar el flujo de datos entre el transmisor y el receptor, y verificar que los mismos lleguen a destino sin errores.

4.2.2.1. Multiplexado de protocolos


Esta subcapa brinda la posibilidad de mantener mltiples conexiones en simultneo haciendo uso de la subcapa de control de acceso al medio, que solamente provee un canal de comunicaciones con filtrado de tramas por medio de un identificador de protocolo. La posibilidad de mantener mltiples conexiones permite manejar diversos protocolos de comunicacin en simultneo lo que permite un mejor aprovechamiento del canal de comunicaciones. El estndar IEEE 802.2 [IEEE802.2] define tres tipos de conexiones posibles: no orientado a la conexin sin confirmacin de recepcin, orientado a la conexin y no orientado a la conexin con confirmacin de recepcin. El primer caso corresponde a un tipo de conexin en donde el envo de un mensaje no implica la recepcin del mismo en el correspondiente destino, o bien el destino recibe un mensaje que se almacena en su buffer, y que no es ledo por la capa superior de forma inmediata, y a continuacin se recibe otro mensaje que es almacenado en el mismo buffer donde se encontraba el primer mensaje, perdindose el primer mensaje recibido por no poseer ningn tipo de control de flujo. El segundo caso corresponde a una comunicacin continua de datos (no mensajes aislados) punto a punto, en donde un transmisor y un receptor establecen un canal de comunicacin en donde los datos enviados por el transmisor y son recibidos por el receptor, si ste puede hacerlo; caso contrario el receptor notificar al transmisor que detenga el flujo de datos momentneamente, estableciendo un control de flujo de datos. Por ltimo, el tercer caso corresponde a un tipo FernandoArielBeunza79156 115

Tesis de Grado en Ingeniera Informtica intermedio entre no tener ningn tipo de garanta (primer caso) y tener un canal dedicado en donde fluyen los datos (segundo caso). ste tipo de conexin se orienta a mensajes aislados, pero con confirmacin de recepcin, estableciendo un control de flujo de los mensajes entre el transmisor y receptor. Para el caso particular del modem PLC solamente se implementa el tercer tipo de conexin (no orientado a la conexin con confirmacin de recepcin), como por ejemplo lo hacen CAN y J1850, debido a que los protocolos que se encuentran por encima de la subcapa de control de lgica de enlace emplean mensajes individuales y requieren control de flujo para evitar congestin en el microcontrolador destinatario de los mensajes.

4.2.2.2. Control de flujo de datos


Como se mencion anteriormente, la subcapa de control de lgica de enlace tiene la responsabilidad de controlar el flujo de informacin entre el transmisor y el receptor para evitar congestionar a ste ltimo. Esta funcionalidad slo se implementa en comunicaciones orientadas a la conexin y orientadas a mensajes individuales con confirmacin de recepcin. En ambos casos se emplea la confirmacin de recepcin como indicador para que el transmisor enve ms datos hacia el receptor. De esta forma, el receptor puede indicarle al transmisor que detenga el envo de datos no mandando la confirmacin de recepcin durante un determinado tiempo, despus del cual se entiende que la conexin se ha roto. Los mtodos utilizados para el control de flujo son conocidos por las siglas ARQ [Stallings97], de los cuales se distinguen tres tipos: Stop and Wait, Go-back-N y Selective Reject. El primer tipo consiste en enviar un paquete y esperar a que el receptor enve una confirmacin de recepcin, que en caso de que sta ltima no llegue, se puede suponer despus de un determinado tiempo que el paquete se perdi y debe ser retransmitido. El segundo tipo consiste en enviar varios paquetes en forma consecutiva y esperar la confirmacin de recepcin. Dicha confirmacin puede notificar que llegaron todos los paquetes o que llegaron hasta un determinado nmero de secuencias, a partir del cual el transmisor debe retransmitirlos. Por ltimo, el tercer tipo consiste en enviar varios paquetes en forma consecutiva y en caso de que se pierdan algunos de stos, el receptor slo pide la retransmisin de los paquetes perdidos. Debido a que el modem PLC no dispone de demasiada memoria para almacenar una secuencia de paquetes, resulta inadecuado implementar un ARQ basado en Go-back-N o Selective Reject. Por simplicidad se implementa un Stop and Wait, ya que slo requiere tener un buffer que pueda contener un slo paquete. El mecanismo utilizado para confirmar la recepcin del paquete en destino es mediante la utilizacin de la funcin de filtrado de paquetes provisto por la subcapa de control de acceso al medio. Cuando se dispone de espacio en el buffer para recibir un paquete, se habilita la recepcin de paquetes asociados al protocolo de la conexin, lo que hace que cada vez que la subcapa de control de acceso al medio confirme la recepcin cada vez que reciba de forma correcta un paquete. Cuando el buffer se encuentra ocupado por un mensaje, automticamente se bloquea la recepcin de un paquete asociado al protocolo de conexin. El bloqueo provoca que la subcapa de control de acceso al medio no reciba paquetes asociados al protocolo bloqueado y notifica al transmisor de que no se aceptan paquetes del protocolo en cuestin hasta que no se desocupe el buffer, momento en el que automticamente se levanta el bloqueo.

116

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

4.2.2.3. Estructura de paquetes


Los paquetes, adems de contener la informacin a enviar, poseen cierta informacin adicional de control necesaria para que el dispositivo destinatario pueda desarmarlos y recuperar la informacin originalmente enviada. Debido a la limitacin de tamao impuesta por la subcapa inmediata inferior, el tamao del paquete no puede superar los 8176 bits (o 1022 bytes), de los cuales quedan disponibles para transporte de informacin 8192 bits (o 1024 bytes) y el resto reservado para informacin de control (ver figura 4.15).
Datos 8176 bits 1022 bytes Cdigo detector de errores 16 bits 2 bytes

Figura 4.15. Estructura de un paquete.


Datos: informacin transportada. La mxima capacidad de transporte son 1022 bytes. Cdigo detector de errores: es un cdigo CRC de 16 bits calculado a partir de todos los bytes que conforman el paquete (excluyendo el cdigo detector de errores).

4.2.2.4. Control de errores


La subcapa de control de lgica de enlace agrega al control de errores realizado por la subcapa de control de acceso al medio, un cdigo CRC de 16 bits. ste cdigo cumple la funcin de verificar la correcta recepcin de toda la informacin de un paquete, ya que la verificacin que realiza la subcapa inferior es a nivel de fragmentos de informacin, y no sobre la totalidad de la misma. Brinda una proteccin adicional por si ocurre una falla en el esquema de reensamblaje de la subcapa de control de acceso al medio.

4.2.2.5. Primitivas de manejo de la subcapa de control de lgica de enlace


A continuacin se detallan las primitivas referentes al manejo de la subcapa de control de lgica de enlace (cuya implementacin se detalla en el Apndice C) que proporcionan las funcionalidades de inicializacin y liberacin de recursos, envo de mensajes y recepcin de los mismo:

void llc_init(void): Inicializa la subcapa de control de acceso al medio, los buffers de mensajes y las funciones de recepcin de mensajes. void llc_release(void): Libera los recursos inicializados por la primitiva anterior. int llc_open(unsigned char prot): Establece una conexin correspondiente al protocolo prot. Devuelve como resultado el nmero de manejador de conexin requerido para enviar y recibir mensajes. 117

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica int llc_close(int hd): Libera la conexin asociada al manejador hd. En caso de xito devuelve como resultado un valor positivo distinto a cero. short int llc_send(int hd, llc_addr dest_addr, unsigned char prio, const void *msg, short int msgsize): Enva un paquete de informacin msg de longitud msgsize con prioridad prio al dispositivo cuya direccin es dest_addr por medio de la conexin asociada al manejador hd. Devuelve como resultado la cantidad de bytes enviados, que coincide con msgsize si la operacin de envo pudo ser realizada. short int llc_receive(int hd, llc_addr addr, void *msg, short int msgsize): Recibe msgsize bytes que se transfieren a msg, de un paquete proveniente de la conexin asociada al manejador hd. Cuando se recibe un paquete desde la subcapa de control de acceso al medio, se invoca la funcin dedicada a recepcin y procesamiento de paquetes. Si luego de interpretar dicho paquete, ste es vlido, se almacena en el buffer correspondiente a la conexin. Esta primitiva transfiere msgsize bytes del contenido del buffer a msg y devuelve la cantidad de bytes transferidos como resultado. Si el buffer se encuentra vaco, queda a la espera de que llegue un paquete. void llc_notify(int hd, void (*func)(llc_addr addr, void *msg, short int msgsize): Esta primitiva brinda la posibilidad de definir una funcin func que se ejecute cuando se recibe un paquete de la conexin asociada al manejador hd. Dicha funcin debe tener definidos como parmetros addr, msg y msgsize, que cumplen la misma funcin que en la primitiva anterior. El objetivo de sta primitiva es poder procesar la informacin que transporta el paquete de forma inmediata a la recepcin de la misma, sin bloquear el microcontrolador, como ocurre con la anterior primitiva. int llc_poll(int hd): Esta primitiva verifica el estado del buffer de la conexin asociada al manejador hd. Devuelve como resultado uno si el buffer contiene un paquete a la espera de ser recibido mediante la primitiva llc_receive. Si el buffer se encuentra vaco el resultado devuelto es cero. De sta forma puede implementarse una espera no bloqueante utilizando la primitiva llc_receive. int llc_status(void): Esta primitiva verifica el estado del dispositivo. Devuelve como resultado un valor positivo distinto a cero si el dispositivo se encuentra operativo. Si la interfaz fsica se encuentra inactivo debido a la ocurrencia de fallas el resultado devuelto es cero. int llc_getaddress(llc_addr addr): Esta primitiva devuelve la direccin fsica asignada al dispositivo.

El conjunto de primitivas descripto abstrae en dos primitivas la inicializacin y liberacin de los recursos utilizados por la subcapa de control de lgica de enlace, en seis primitivas el envo y recepcin (en modo bloqueante y no bloqueante) de paquetes, y en dos primitivas la consulta de informacin sobre el dispositivo. Los paquetes recibidos son los que cuya direccin destinataria es la del receptor. Adems se controla que los paquetes no contengan errores, con un control adicional 118 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica que complementa al control de errores realizado por la subcapa inferior de control de acceso al medio).

4.2.3. Protocolo de resolucin de direcciones


El protocolo de resolucin de direcciones (conocido como ARP) es ajeno a las cuestiones referente a la capa de enlace, pero se sita en esta capa para brindar soporte de resolucin de direcciones lgicas utilizadas por la capa inmediata superior (capa de red).

4.2.3.1. Principio de funcionamiento


La necesidad de la existencia de ste protocolo radica en que es necesario tener la capacidad de definir la direcciones de los dispositivos. Cuando se trat el tema de la subcapa de control de acceso al medio, se hizo mencin a la necesidad de tener direcciones fsicas nicas e irrepetibles para resolver cuestiones propias de sta subcapa. Pero a un nivel superior existen inconvenientes en no poder definir las direcciones de los dispositivos. Uno de los inconvenientes que presenta el esquema de direcciones fsicas es que no se pueden conformar redes lgicas de dispositivos. Al no poderse modificar la direccin fsica, el usuario no puede agrupar un conjunto de dispositivos para conformar una red lgica (sobre un mismo medio fsico), ya que sto depende de poder definir un identificador de red que generalmente se encuentra asociado a las direcciones asignadas a cada dispositivo. Otro problema importante, que surge a partir del modelo de capas, es que los esquemas de direccionamiento son propios de cada capa. No es conveniente trasladar un mismo esquema de direccionamiento a lo largo de las capas, ya que un cambio en ste esquema provocara un cambio en el resto de las capas, algo que trata de evitar el modelo de capas. Por ste motivo es importante que la capa de enlace tenga a cargo el esquema de direccionamiento fsico, y la capa inmediata superior (capa de red) tenga su propio esquema de direccionamiento. El mantener dos esquemas de direccionamiento requiere de un mecanismo de traduccin, y en ste punto surge la necesidad de disponer de un protocolo de resolucin de direcciones, encargado de realizar dicha traduccin. El protocolo de resolucin de direcciones consiste bsicamente en mantener en cada dispositivo fsico (en este caso modem PLC) una tabla con una serie de direcciones lgicas por cada protocolo de red que haga uso de la capa de enlace. Dichas direcciones pueden ser creadas o eliminadas por la capa de red independientemente de las direccin fsica preasignada al dispositivo fsico. Cuando la capa de red necesita establecer una comunicacin con otro dispositivo, sta solamente conoce la direccin lgica propia del protocolo de red; por lo cual requiere consultar al resto de los dispositivos conectados para saber a cual de ellos se le ha asignado la direccin lgica requerida. La consulta consiste en un mensaje de broadcast (ver figura 4.16) que llega en forma simultnea a todos los dispositivos, y slo emitir una respuesta a dicha consulta el dispositivo que contenga en su tabla de direcciones lgicas la direccin solicitada. Junto con el mensaje de respuesta viaja la direccin fsica asociada a la direccin lgica suministrada, por lo cual el dispositivo que realiz la consulta conoce la direccin fsica en el momento que recibe la respuesta, y con sta direccin fsica puede establecer la comunicacin. Para el caso particular del presente trabajo, se ha implementado una versin del protocolo de resolucin de mensajes basada en el protocolo ARP para redes Ethernet [RFC826], que respeta los principio fundamentales de funcionamiento, pero se la adapta a medida de los requerimientos y disponibilidad de recursos del modem PLC.

FernandoArielBeunza79156

119

Tesis de Grado en Ingeniera Informtica

Figura 4.16. Funcionamiento del protocolo ARP.

4.2.3.2. Estructura de mensajes


Los mensajes que maneja ste protocolo pueden ser de consulta por una direccin fsica o de respuesta a una consulta. En ambos casos el mensaje transporta el protocolo y la direccin lgica asociada, mientras que la direccin fsica (para el caso del mensaje de respuesta) se encuentra dentro de los campos de control de los paquetes de la subcapa de control de lgica de enlace, que es el canal de comunicacin utilizado para la resolucin de direcciones. Dicha direccin fsica se obtiene en el mismo momento en que se recibe el mensaje de respuesta, debido a que las primitivas de recepcin de paquetes de la subcapa de control de lgica de enlace devuelven la direccin fsica del dispositivo que dio origen al paquete y el contenido de dicho paquete, que en este caso es el mensaje. El protocolo de resolucin de direcciones define una nica estructura de mensaje que permite consultar por una direccin y responder por dicha consulta:
Tipo de Direccin Protocolo mensaje lgica 8 bits 1 byte 8 bits 1 byte 32 bits 4 byte

Figura 4.17. Estructura de un mensaje.

Tipo de mensaje: si el valor es 01 (hexadecimal), el mensaje es de consulta por una direccin fsica. En cambio, si el valor es 02 (hexadecimal), el mensaje es de respuesta a una consulta. Protocolo: identificador de protocolo correspondiente a la direccin lgica. Direccin lgica: direccin de 32 bits destinada a protocolos de capa de red.

4.2.3.3. Primitivas de manejo del protocolo de resolucin de direcciones


A continuacin se detallan las primitivas referentes al manejo de la subcapa de control de lgica de enlace (cuya implementacin se detalla en el Apndice C):

void arp_init(void):

120

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica Inicializa los recursos referentes al manejo del protocolo de resolucin de direcciones lgicas (tabla de direcciones lgicas, etc.).

void arp_release(void): Libera los recursos inicializados por la primitiva anterior. int arp_addaddress(unsigned char prot, logaddr addr): Agrega una nueva direccin lgica addr correspondiente al protocolo de capa de red prot a la tabla de direcciones lgicas. Si la direccin lgica pudo agregarse devuelve como resultado un valor positivo distinto de cero. int arp_deladdress(unsigned char prot, logaddr addr): Elimina la direccin lgica addr correspondiente al protocolo de capa de red prot de la tabla de direcciones lgicas. En caso de xito devuelve como resultado un valor positivo distinto a cero. int arp_getaddress(unsigned char prot, logaddr laddr, mac_addr *paddr): Devuelve la direccin fsica paddr asociada a la direccin lgica laddr correspondiente al protocolo de capa de red prot. Esta primitiva es la encargada de consultar al resto de los modems PLC para averiguar cual de ellos tiene en su tabla de direcciones lgicas la direccin solicitada. El modem PLC que contenga dicha direccin le responder al modem que realiz la consulta con su direccin fsica. En caso de xito devuelve como resultado un valor positivo distinto a cero.

4.2.4. Primitivas de manejo de la capa de enlace


A continuacin se detallan las primitivas referentes al manejo de la capa de enlace. Dichas primitivas brindan una interfaz que encapsulan hacia la capa superior (capa de red) las primitivas de control de lgica de enlace y del protocolo de resolucin de direcciones (cuyas implementaciones se detalla en el Apndice C):

void dl_init(unsigned char iface): Inicializa la subcapa de control de lgica de enlace y el protocolo de resolucin de direcciones lgicas asociados a la interfaz fsica iface. void dl_release(unsigned char iface): Libera los recursos inicializados por la primitiva anterior asociados a la interfaz fsica iface. int dl_open(unsigned char iface , unsigned char prot): Establece una conexin correspondiente a la interfaz fsica iface y al protocolo prot. Devuelve como resultado el nmero de manejador de conexin requerido para enviar y recibir mensajes. int dl_close(int hd): Libera la conexin asociada al manejador hd. En caso de xito devuelve como resultado un valor positivo distinto a cero.

FernandoArielBeunza79156

121

Tesis de Grado en Ingeniera Informtica

short int dl_send(int hd, llc_addr dest_addr, unsigned char prio, const void *msg, short int msgsize ): Enva un paquete de informacin msg de longitud msgsize con prioridad prio al dispositivo cuya direccin es dest_addr por medio de la conexin asociada al manejador hd. Devuelve como resultado la cantidad de bytes enviados, que coincide con msgsize si la operacin de envo pudo ser realizada. short int_t dl_receive(int hd, llc_addr addr, void *msg, short int msgsize): Recibe msgsize bytes que se transfieren a msg, de un paquete proveniente de la conexin asociada al manejador hd. Si el buffer se encuentra vaco, queda a la espera de que llegu un paquete. void dl_notify(int hd, void (*func)(llc_addr addr, void *msg, short int msgsize): Esta primitiva brinda la posibilidad de definir una funcin func que se ejecute cuando se recibe un paquete de la conexin asociada al manejador hd. Dicha funcin debe tener definidos como parmetros addr, msg y msgsize, que cumplen la misma funcin que en la primitiva de anterior. El objetivo de sta primitiva es poder procesar la informacin que transporta el paquete de forma inmediata a la recepcin de la misma, sin bloquear el microcontrolador, como ocurre con la anterior primitiva. int dl_poll(int hd): Esta primitiva verifica el estado del buffer de la conexin asociada al manejador hd. Devuelve como resultado uno si el buffer contiene un paquete a la espera de ser recibido mediante la primitiva dl_receive. Si el buffer se encuentra vaco el resultado devuelto es cero. De sta forma puede implementarse una espera no bloqueante utilizando la primitiva dl_receive. int dl_getaddress(unsigned char iface, dl_addr addr): Devuelve la direccin fsica addr asociada a la interfaz fsica iface. En caso de xito devuelve como resultado un valor positivo distinto a cero. int dl_addlogaddress(unsigned char iface, unsigned char prot, logaddr addr): Agrega una nueva direccin lgica addr correspondiente al protocolo de capa de red prot a la tabla de direcciones lgicas asociada a la interfaz fsica iface. Si la direccin lgica pudo agregarse devuelve como resultado un valor positivo distinto de cero. int dl_dellogaddress(unsigned char iface, unsigned char prot, logaddr addr): Elimina la direccin lgica addr correspondiente al protocolo de capa de red prot de la tabla de direcciones lgicas asociada a la interfaz fsica iface. En caso de xito devuelve como resultado un valor positivo distinto a cero. int dl_getphyaddress(unsigned char iface, unsigned char prot, logaddr laddr, llc_addr paddr): Devuelve la direccin fsica paddr de la interfaz fsica iface asociada a la direccin lgica laddr correspondiente al protocolo de capa de red prot. En caso de xito devuelve como resultado un valor positivo distinto a cero. int dl_status(unsigned char iface):

122

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica Esta primitiva verifica el estado de la interfaz fsica iface. Devuelve como resultado un valor positivo distinto a cero si el dispositivo se encuentra operativo. Si la interfaz fsica se encuentra inactivo debido a la ocurrencia de fallas el resultado devuelto es cero.

short int dl_getpayloadsize(unsigned char iface): Esta primitiva devuelve la cantidad mxima de bytes que puede contener un paquete.

El conjunto de primitivas descripto abstrae en dos primitivas la inicializacin y liberacin de los recursos utilizados por la cada de enlace, en seis primitivas el envo y recepcin (en modo bloqueante y no bloqueante) de paquetes, en cuatro primitivas el manejo de direcciones lgicas y fsicas, y en dos primitivas adicionales la consulta de informacin sobre las interfaces fsicas.

4.3. Capa de red


La capa de enlace es responsable del transporte de la informacin a travs de un medio fsico comn, libre de errores y con control de flujo entre el transmisor y el receptor. Pero es necesario tener la capacidad de poder crear redes lgicas a partir de redes fsicas, y que todos los nodos integrantes de una red lgica se puedan comunicar entre s independientemente de la red fsica a la que se encuentren conectados.

4.3.1. Modelo de comunicaciones


Existen dos formas de comunicacin posible: las comunicaciones orientadas a la conexin y las no orientados a la conexin. La primer forma de comunicacin consiste en que tanto el transmisor como el receptor se sincronicen en un determinado instante, por medio de un protocolo de intercambio de mensajes, para establecer un canal de comunicaciones donde la informacin fluya libremente de un extremo a otro y dicho flujo finalice cuando alguno o los dos extremos cierren el canal. Este mecanismos es semejante a la comunicaciones por medio de la red telefnica donde una persona llama a otra y la comunicacin se establece cuando sta ltima atiende, intercambian informacin durante un tiempo, y la comunicacin finaliza cuando la persona que origin la comunicacin cuelga su telfono. La ventaja de ste modelo es que se puede implementar un canal de comunicaciones confiable (donde no se pierda informacin) de forma relativamente simple entre dos dispositivos. En la segunda forma de comunicacin el transmisor y el receptor actan de forma asincrnica, ya que el primero enva un mensaje y despus de un tiempo lo recibe el receptor. En ste caso no se establece un canal de comunicacin como en la forma anterior y la informacin no fluye libremente sino que se reduce a un mensaje individual. Un ejemplo tpico de esta forma de comunicacin es el correo en el cual una persona escribe su mensaje en una carta, sta va al correo y el correo se encarga de llevarla hasta la persona destinataria. Como se puede observar no se establece una comunicacin punto a punto como con un comunicacin orientada a la conexin y no resulta confiable porque al no estar sincronizados el transmisor y el receptor, ste ltimo no puede confirmarle la llegada del mensaje al transmisor. Pero a pesar de stos inconvenientes, es una forma de comunicacin ms simple de implementar que la primera y no est limitada a solamente dos dispositivos pudiendo implementar mensajes de difusin. Las redes se orientan por alguno de los dos modelos de comunicaciones anteriores, por ejemplo la red telefnica es orientada a la conexin y el correo es no orientado a la conexin. En el FernandoArielBeunza79156 123

Tesis de Grado en Ingeniera Informtica caso particular del presente trabajo se busca simpleza y capacidad de difusin, lo que orienta la eleccin hacia el modelo no orientado a la conexin. Emplear ste modelo de comunicacin implica que debe buscarse un mecanismo adicional para garantizar la confiabilidad. Por ejemplo, las redes IP [Stallings97], son redes que hacen su mejor esfuerzo para que los mensajes lleguen a destino, pero no brindan garanta de sto ltimo, delegando la confiabilidad al protocolo de transporte TCP [Stallings97]. Un esquema similar presenta LonWorks, en donde la confiabilidad tambin se traslada a la capa de transporte. En las redes utilizadas en automviles, las comunicaciones tambin son no orientadas a la conexin, pero a diferencia del modelo IP, no delegan el problema de la confiabilidad a capas superiores, ya que no implementan todas las capas del modelo OSI, tendiendo a resolver ste problema a nivel de capa de enlace. Las redes CAN y J1850 implementan un sistema de confirmacin de recepcin para mensajes de difusin (multicast y broadcast). Las redes D2B y MOST se basan en una topologa anillo que permite confirmar la recepcin de los mensajes. En el caso particular del presente trabajo, se sigue el modelo de capas como lo hace el modelo IP y LonWorks, pero tambin se busca la simpleza y capacidad de difusin de una comunicacin no orientada a la conexin, con el agregado de confiabilidad, siguiendo tambin las ideas de las redes de automviles. Como ya se mencion con anterioridad, la capa de enlace propuesta permite garantizar que mensajes de difusin tengan confirmacin de recepcin (igual que CAN y J1850), no trasladando el problema a las capas superiores, para simplificar la implementacin de stas ltimas.

4.3.2. Esquema de direccionamiento


Debido a que el objetivo de la capa de red es poder crear redes lgicas sobre una o varias redes fsicas, y que dichas redes lgicas sean independientes de las caractersticas de la red fsica, uno de los puntos para lograr dicha independencia es implementar un esquema de direccionamiento independiente al provisto por la red fsica (capa de enlace). Cualquier esquema de direccionamiento debe aprovechar las funcionalidades del protocolo de resolucin de direcciones (ARP), provisto por la capa de enlace, que permite trabajar con un esquema de direcciones de 32 bits de longitud. sto resulta suficiente para poder individualizar a cada nodo de la red lgica, pudiendo cada nodo tener una o varias direcciones lgicas. Se reserva la direccin cero para indicar que el destinatario del mensaje son todos los nodos de la red (direccin de broadcast). Adems del esquema de direccionamiento lgico, se provee otro esquema basado en el identificador de mensaje similar al sistema empleado por las redes CAN y J1850 (modo de direccionamiento funcional). ste esquema consiste en tener una tabla de filtrado de mensajes en cada nodo, en donde se almacena una lista de los identificadores de mensajes que el nodo tiene inters en recibir, ignorando los mensajes que contengan un identificador no presente en su lista de identificadores. De este modo se tienen dos sistemas de direccionamiento, similar al esquema propuesto por J1850 (modo de direccionamiento fsico y modo de direccionamiento funcional); uno para identificar un nodo en particular y otro para identificar una funcionalidad en particular que puede llevarse a cabo por uno o varios nodos. Se pueden utilizar cualquiera de los sistemas en forma separada o en forma conjunta. Si se trabaja utilizando solamente la direccin de broadcast y el direccionamiento por identificador de mensaje se tiene un sistema de direccionamiento similar al propuesto por CAN y J1850 (modo de direccionamiento funcional). ste modo de trabajo mencionado permite implementar un esquema de grupos de difusin que ms adelante se desarrollar en profundidad.

124

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Figura 4.18. Ejemplo de direccionamiento por identificador de mensaje.

En la figura 4.18 se puede observar un ejemplo del funcionamiento del esquema de direccionamiento por identificador de mensaje y utilizando como identificador de nodo el identificador destinado para mensajes de broadcast. Existen tres dispositivos, uno es el tablero que enva rdenes a las luces delanteras y traseras de encenderse o apagarse por medio de un mensaje cuyo identificador es 01, y cada una de stas puede reportar algo al tablero por medio de un mensaje cuyo identificador es 02 (para las luces delanteras) o 03 (para las luces traseras). El tablero no conoce como se encuentran conectados fsicamente los otros dispositivos, slo sabe que enviando un mensaje con identificador 01 se encendern o apagarn las luces y que las luces podrn reportar al tablero alguna falla, por ejemplo, enviando mensajes con identificadores 02 y 03. El tablero no necesita saber como se conforman las redes fsicas, slo enva y recibe mensajes; dejando a la capa de red el trabajo de encaminar cada mensaje para que llegue a su destinatario. Si por algn motivo el tablero quisiera enviar un mensaje especfico para las luces delanteras, y no las traseras, podra realizarse utilizando el identificador de nodo asignado a las luces delanteras, o bien si no se desea trabajar con identificadores de nodo reservar un identificador de mensaje destinado solamente a las luces delanteras. Como se puede observar en el ejemplo anterior, el esquema de direccionamiento es lo suficientemente flexible para poder implementar en capas superiores un sistema de mensajera por medio de canales de difusin, asociando a cada identificador de mensaje a un grupo de difusin especfico.

4.3.3. Estructura de mensajes


Los mensajes, adems de contener porciones del mensaje a enviar, poseen cierta informacin adicional de control necesaria para que el dispositivo destinatario pueda desarmarlos y recuperar la informacin originalmente enviada. La informacin de control ocupa 5 bytes dejando el resto reservado para el campo de datos, cuyo tamao mximo depende de la interfaces fsicas a las cuales se encuentre conectado el nodo. Si slo se encuentra conectado a una sola interfaz, sta interfaz determinar la cantidad de informacin que se puede enviar. En caso de ser varias las interfaces, ser la de menor capacidad la que determinar la cantidad de informacin que se puede enviar.

FernandoArielBeunza79156

125

Tesis de Grado en Ingeniera Informtica

Versin 8 bits 1 byte

Identificador Protocolo Tamao de mensaje 8 bits 1 byte 8 bits 1 byte 16 bits 2 bytes

Datos (capacidad mxima de capa de enlace - 40) bits (capacidad mxima de capa de enlace - 5) bytes

Figura 4.19. Estructura de un mensaje.


Versin: identificador de versin del protocolo de red. Identificador de mensaje: identificador de mensaje asociado al contenido del campo de datos. Protocolo: identificador de protocolo asociado al contenido del campo de datos. Tamao total: especifica el tamao del mensaje. El mximo tamao depende de la capacidad mxima que provea la capa de enlace. Datos: informacin transportada.

4.3.4. Primitivas de manejo de la capa de red


A continuacin se detallan las primitivas referentes al manejo de la capa de red (cuya implementacin se detalla en el Apndice C) que proporcionan las funcionalidades de inicializacin y liberacin de recursos, envo de mensajes y recepcin de los mismos y manejo de la tabla de encaminado de mensajes:

void net_init(void): Inicializa la capa de red, las interfaces fsicas, el buffer de mensajes y la funcin de recepcin de mensajes. void net_release(void): Libera los recursos inicializados por la primitiva anterior. short int net_send(net_nodeid nodeid, net_msgid msgid, unsigned char prio, unsigned char prot, const void *msg, short int msgsize): Enva un mensaje msg de longitud msgsize, cuyo identificador es msgid, con prioridad de envo prio, por medio de la red al nodo cuyo identificador es nodeid. Adems el mensaje enviado corresponde a un protocolo de capa superior que puede ser especificado por medio del parmetro prot. Si el identificador de nodo nodeid tiene valor cero, el mensaje es enviado a todos los nodos de todas las redes a las que se tiene acceso. Devuelve como resultado la cantidad de bytes enviados, que coincide con msgsize si la operacin de envo pudo ser realizada. short int net_receive(net_msgid *msgid, unsigned char *prot, void *msg, short int msgsize):

126

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica Recibe msgsize bytes que se transfieren a msg, de un mensaje recibido a travs de la red cuyo identificador es msgid. Cuando se recibe un mensaje por medio de la capa de enlace, se invoca la funcin dedicada a recepcin y procesamiento de paquetes. Si luego de interpretar un paquete recibido, ste resulta vlido, se almacena el mensaje recibido en el buffer de la capa de red. El mensaje recibido tiene asociado un protocolo de la capa superior devuelto a travs de prot. Esta primitiva transfiere msgsize bytes del contenido del buffer a msg y devuelve la cantidad de bytes transferidos como resultado. Si el buffer se encuentra vaco, queda a la espera de que algn mensaje.

void net_notify(void (*func)(net_msgid msgid, unsigned char prot, void *msg, short int msgsize)): Esta primitiva brinda la posibilidad de definir una funcin func que se ejecute cuando se recibe un mensaje a travs de la red. Dicha funcin debe tener definidos como parmetros prot, msg y msgsize, que cumplen la misma funcin que en la primitiva de anterior. El objetivo de sta primitiva es poder procesar la informacin que transporta el mensaje de forma inmediata a la recepcin del mismo, sin bloquear el microcontrolador, como ocurre con la anterior primitiva. int net_poll(void): Esta primitiva verifica el estado del buffer. Devuelve como resultado uno si el buffer contiene un mensaje a la espera de ser recibido mediante la primitiva net_receive. Si el buffer se encuentra vaco el resultado devuelto es cero. De sta forma puede implementarse una espera no bloqueante utilizando la primitiva net_receive. int net_addaddr(net_nodeid nodeid): Esta primitiva permite agregar un nuevo identificador de nodo nodeid. Si el identificador de nodo pudo agregarse devuelve como resultado un valor positivo distinto de cero, caso contrario devuelve cero. int net_deladdr(net_nodeid nodeid): Esta primitiva permite eliminar un identificador de nodo nodeid ya existente. Devuelve como resultado un valor distinto de cero si la operacin pudo ejecutarse con xito, caso contrario devuelve valor cero si la eliminacin no pudo ser concretada. int net_addmsgid(net_msgid msgid): Esta primitiva permite agregar un nuevo identificador de mensaje msgid en la tabla de filtrado de mensajes. Si el identificador de mensaje pudo ser agregado a la tabla de filtrado devuelve como resultado un valor positivo distinto de cero, caso contrario devuelve cero. int net_delmsgid(net_msgid msgid): Esta primitiva permite eliminar un identificador de mensaje msgid ya existente en la tabla de filtrado de mensajes. Devuelve como resultado un valor distinto de cero si la operacin pudo ejecutarse con xito, caso contrario devuelve valor cero si la eliminacin no pudo ser concretada. int net_status(void): Esta primitiva verifica si el nodo posee alguna interfaz fsica activa por la cual pueda comunicarse con otros nodos. Devuelve como resultado un valor positivo distinto a cero 127

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica si el nodo se encuentra operativo. Si no hay ninguna interfaz fsica activa el resultado devuelto es cero.

short int net_getpayloadsize(void): Esta primitiva devuelve la cantidad mxima de bytes que puede contener un mensaje para poder ser enviado por cualquiera de las interfaces fsicas a las cuales se encuentra conectado el nodo.

El conjunto de primitivas descripto abstrae en dos primitivas la inicializacin y liberacin de los recursos utilizados por la capa de red, en cuatro primitivas en el envo y recepcin (en modo bloqueante y no bloqueante) de mensajes, y finalmente, mediante seis primitivas especiales, se permite la configuracin del nodo y obtener informacin sobre el mismo.

4.4. Capa de transporte


La capa de transporte es responsable de que la informacin transportada por medio de la capa de red llegue de forma confiable a todos los destinos en un mismo orden. En caso de que lo anterior no se logre, sta capa debe detectarlo para notificarle a la capa de sesin (capa superior) para que pueda arbitrar los medios para resolver esta situacin.

4.4.1. Comunicacin por grupos de difusin


Existen diversas formas de establecer una comunicacin entre varios dispositivos presentes en una red, y una de las ms simples de ver es por medio de un protocolo punto a punto. sto consiste en tener identificados a todos los dispositivos unvocamente y asociarles a cada uno de stos una o varias funcionalidades en particular, entonces cuando un dispositivo requiera de la funcionalidad que provee otro, el primero le enva un mensaje al segundo solicitando el requerimiento. Un ejemplo de ste caso podra ser el sistema de iluminacin exterior de un automvil en donde el dispositivo que genera el requerimiento es el mando de encendido de los faros exteriores y el dispositivo que lleva a cabo la accin son los faros, entonces cuando el usuario acciona el encendido de las luces, el dispositivo genera un mensaje hacia cada faro exterior para que se activen. Los inconvenientes presentes en un protocolo punto a punto es que el desarrollador del dispositivo que acciona la iluminacin debe conocer la direccin de cada faro exterior para enviar a cada uno de ellos la orden de encendido o apagado. sto no brinda posibilidad de agregar nuevo dispositivos, porque si el desarrollador del dispositivo que acciona la iluminacin no prevee el agregado de nuevos dispositivos de iluminacin, y stos ltimo, por ms que se encuentren instalados, al no recibir el mensaje de encendido no realizarn accin alguna. sto podra superarse si se trabajar con un esquema de mensajes de difusin como los utilizados por CAN y J1850.

128

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Figura 4.20. Ejemplo de comunicacin punto a punto.

La propuesta de este trabajo es tomar las ideas de CAN y J1850, e implementar un esquema de difusin. Dicho esquema responde al modelo de comunicaciones orientado a grupos. En este modelo los dispositivos conforman grupos de difusin, volviendo al ejemplo anterior, se podra definir un grupo referente al sistema de iluminacin exterior y los participantes o miembros seran el mando de accionamiento y los faros exteriores. El mensaje con la orden de encendido o apagado de los faros es nico con garanta de que la orden le llegue a todos los destinatarios o caso contrario a ninguno. Esto ltimo es lo que se conoce como difusin confiable (o reliable multicast). LonWorks tambin implementa un esquema de difusin con confirmacin, pero a diferencia de CAN y J1850, la confirmacin de recepcin est dada por el primer destinatario que confirme la recepcin, lo cual no permite garantizar que todos los dispositivos recibieron el mensaje. El modelo de comunicacin orientado a grupos involucra varios temas adems de la difusin confiable, como la gestin de los miembros de grupo y ordenamiento de los mensajes.

Figura 4.21. Ejemplo de comunicacin por difusin.

Evidentemente una comunicacin orientada a grupos resulta mucho ms compleja que la punto a punto, por lo cual todas las problemticas planteadas no se pueden resolver en una sola capa. Por este motivo desde las primeras capas se viene introduciendo mejoras a fin de poder implementar el modelo de comunicacin mencionado de forma eficiente. La mejoras comienzan en la capa de enlace cuando se implementa un mecanismo de confirmacin de recepcin para mensajes de broadcast, luego en la capa de red donde se plantea un esquema de direccionamiento que permite la introduccin de un esquema de grupos de difusin a partir de la capa de transporte. La capa de transporte, adems de introducir por primera vez el concepto de grupos de difusin, se encarga de garantizar la llegada de todos los mensajes que se difundan por un grupo, como as tambin el orden de llegada. En caso de que por una falla, se pierdan las anteriores condiciones, la capa de transporte desactiva el dispositivo y notifica de la situacin a la capa de sesin, encargada de gestionar una posible reconexin del dispositivo. Los grupos de difusin se conforman de un dispositivo propietario del grupo encargado de difundir mensajes por medio del grupo y de un o varios dispositivos miembros del grupo, destinatarios de los mensajes. Este esquema de comunicacin se implementa utilizando la difusin de mensajes provista por la capa de red sumada al esquema de filtrado de mensajes, tambin provisto por la capa de red.

FernandoArielBeunza79156

129

Tesis de Grado en Ingeniera Informtica

4.4.2. Esquema de identificacin


La capa de transporte debe proveer un esquema de identificacin que sea independiente del esquema de direccionamiento que utiliza la capa inferior (capa de red) para poder ser portable a otras implementaciones de redes. El esquema de identificacin no se basa en identificar a cada uno de los dispositivos, sino que a identificar los canales de comunicacin utilizados para difundir los mensajes. Cada canal de comunicacin se denomina grupo de difusin, y se encuentra conformado por un dispositivo propietario y mltiples dispositivos miembros del grupo. El propietario de un grupo de difusin es el nico dispositivo que puede enviar mensajes, que el resto de los miembros recibe y procesa. Cada grupo de difusin puede verse como una estructura maestro/esclavo, el sentido de las comunicaciones es solamente desde el maestro o propietario hacia los esclavos o miembros. La diferencia con la estructura tradicional maestro/esclavo, es que pueden existir mltiples grupos de difusin, sobre una misma red fsica, lo cual permitira comunicaciones bidireccionales. Por ejemplo, se tiene un dispositivo, que puede ser el tablero de instrumentos que tiene la funcin de reportar el estado del vehculo, y junto a l diversos mandos como, por ejemplo, el encendido de luces. Puede existir un grupo de difusin asociado a las luces en donde el tablero es el propietario y las luces miembros de ese grupo, y el tablero enva mensajes de encendido y apagado hacia las luces. Adems, cada luz puede tener asociado un grupo de difusin en donde es propietario, y el tablero es miembro de cada uno de los grupos de difusin de cada luz, para conocer el estado de las mismas, por medio de mensajes que enva cada una de las luces hacia el tablero. As como este ejemplo, se pueden pensar otros mucho ms complejos donde intervengan ms dispositivos. La cantidad de grupos de difusin que pueden existir se limitan a 255, cada grupo debe poseer un propietario del mismo, y no existe lmites de dispositivos que pueden ser miembro del grupo. Cada dispositivo puede ser propietario de uno o varios grupos de difusin, o bien no ser propietario de ninguno; sto viene dado a la informacin que desee compartir el dispositivo con el resto de los dispositivos de la red. El lmite de dispositivos est dado por lmites fsicos de las redes, no por el esquema de identificacin propuesto.

4.4.3. Mensajes
La capa de transporte presenta dos tipos de mensajes: en secuencia y fuera de secuencia. Los primeros se tratan de mensajes enviados con baja prioridad, que obligatoriamente deben ser recibidos por todos los dispositivos miembros de un grupo de difusin, cumpliendo de esta forma con las condiciones exigidas por un esquema de comunicacin de difusin confiable. Este tipo de mensaje sacrifica velocidad por confiabilidad de recepcin, y pueden ser utilizados, por ejemplo, para enviar informacin de configuracin de dispositivos. El otro tipo de mensajes son los que se enva fuera de secuencia, en donde la capa de transporte hace su mejor esfuerzo para cumplir las exigencias de una comunicacin por difusin confiable, pero no brinda garanta. Este tipo de mensaje se enva con alta prioridad a diferencia de los del primer tipo, y su aplicacin est destinada para enviar rdenes a dispositivos, en donde es ms importante recibir el mensaje en el tiempo correspondiente, o en su defecto no recibirlo; que recibirlo fuera de tiempo. Ambos tipos de mensaje emplean una nica estructura de mensaje como la descripta en la figura 4.22.

130

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Versin Secuencia 8 bits 1 byte 8 bits 1 byte

Datos (capacidad mxima de capa de red - 16) bits (capacidad mxima de capa de red - 2) bytes

Figura 4.22. Estructura de un mensaje.


Versin: identificador de versin del protocolo de transporte. Secuencia: especifica el nmero de secuencia del mensaje. El nmero de secuencia -1 indica que el mensaje se encuentra fuera de secuencia. Datos: informacin transportada por el mensaje. La mxima capacidad de transporte depende la capacidad que brinda la capa de red.

4.4.4. Primitivas de manejo de la capa de transporte


A continuacin se detallan las primitivas referentes al manejo de la capa de transporte (cuya implementacin se detalla en el Apndice C) que proporcionan las funcionalidades de inicializacin y liberacin de recursos, envo de mensajes y recepcin de los mismos:

void tp_init(void): Inicializa la capa de transporte, los buffers de mensajes y la funcin de recepcin de mensajes. Tambin establece el identificador de dispositivo dev. void tp_release(void): Libera los recursos inicializados por la primitiva anterior. short int tp_send(tp_grpid grpid, unsigned char nosec, const void *msg, short int msgsize): Enva un mensaje msg de longitud msgsize por el grupo de difusin grpid. Por medio de la activacin del indicador nosec, el mensaje puede excluirse de la secuencia de mensajes enviados, lo que significa que ante una eventual resincronizacin del modem PLC, el mensaje no ser recuperado. Devuelve como resultado la cantidad de bytes enviados, que coincide con msgsize si la operacin de envo pudo ser realizada. short int tp_receive(tp_grpid *grpid, void *msg, short int msgsize): Recibe msgsize bytes que se transfieren a msg, de un mensaje recibido a travs del grupo de difusin grpid. Cuando se recibe un mensaje de la capa de red, se invoca la funcin dedicada a recepcin y procesamiento de mensajes. Si luego de interpretar el mensaje, ste resulta vlido, se almacena en el buffer de la capa de transporte. Esta primitiva transfiere msgsize bytes del contenido del buffer a msg y devuelve la cantidad de bytes transferidos como resultado. Si el buffer se encuentra vaco, queda a la espera de que llegue un mensaje. void tp_notify(void (*func)(tp_grpid grpid, void *msg, short int msgsize)): Esta primitiva brinda la posibilidad de definir una funcin func que se ejecute cuando se recibe un mensaje. Dicha funcin debe tener definidos como parmetros grpid, msg y 131

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica msgsize, que cumplen la misma funcin que en la primitiva de anterior. El objetivo de sta primitiva es poder procesar la informacin que transporta el mensaje de forma inmediata a la recepcin del mismo, sin bloquear el microcontrolador, como ocurre con la anterior primitiva.

int tp_poll(void): Esta primitiva verifica el estado del buffer de la capa de transporte. Devuelve como resultado uno si el buffer contiene un mensaje a la espera de ser recibido mediante la primitiva tp_receive. Si el buffer se encuentra vaco el resultado devuelto es cero. De sta forma puede implementarse una espera no bloqueante utilizando la primitiva tp_receive. int tp_setownergrp(tp_grpid grpid): Establece que el modem PLC es propietario de un grupo de difusin grpid lo que le permite enviar mensajes por medio del grupo que posee. Devuelve como resultado un valor positivo distinto de cero si se pudo establecer la propiedad del grupo de difusin, caso contrario devuelve como resultado cero. int tp_setmembergrp(tp_grpid grpid): Establece que el modem PLC es miembro de un grupo de difusin grpid lo que le permite recibir mensajes por medio del grupo del cual es miembro. Devuelve como resultado un valor positivo distinto de cero en caso de xito, caso contrario devuelve como resultado cero. int tp_leavegrp(tp_grpid grpid): Desvincula el modem PLC del grupo de difusin grpid, independientemente de que sea propietario o miembro. En caso de xito devuelve como resultado un valor positivo distinto a cero. int tp_status(void): Esta primitiva verifica si la conexin se encuentra activa o no. Devuelve como resultado un valor positivo distinto a cero si el nodo se encuentra operativo. Si no hay ninguna interfaz fsica activa el resultado devuelto es cero. short int tp_getpayloadsize(void): Esta primitiva devuelve la cantidad mxima de bytes que puede contener un mensaje.

El conjunto de primitivas descripto abstrae en dos primitivas la inicializacin y liberacin de los recursos utilizados por la capa de transporte, en cuatro primitivas la apertura, cierre y deteccin de cambios de estado de la conexin, y en cinco primitivas el envo y recepcin (en modo bloqueante y no bloqueante) de mensajes.

4.5. Capa de sesin


La capa de sesin es responsable de proveer los mecanismos de establecimiento y finalizacin de sesiones entre diferentes aplicaciones usuarias. Adems debe controlar el dilogo entre el dispositivo transmisor y receptor, y sincronizar la informacin recibida por todos los dispositivos. La capa de transporte provee a la capa de sesin un medio confiable de transmisin de

132

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica la informacin durante la existencia de una conexin entre transmisor y receptor, que puede perderse por diversas situaciones. La capa de sesin es la encargada de brindar a las capas superiores un servicio de conexin entre dispositivos que gestione de forma automtica las reconexiones, en caso de que la capa de transporte notifique una prdida de conexin, y que la informacin enviada por un dispositivo hacia varios destinatarios sea la misma (si un dispositivo enva varios mensajes, los destinatarios deben recibirlos todos y en el mismo orden).

4.5.1. Establecimiento de sesiones


Bajo el esquema de grupo de difusin de la capa de transporte existe la garanta de que todos los miembros de un grupo reciben los mismos mensajes en el mismo orden, y cuando un miembro falla en la recepcin se considera que ha abandonado el grupo, conformndose un nuevo grupo con otros miembros (los mismos que el anterior grupo menos el que ha fallado). Lo mismo ocurre cuando ingresa un nuevo miembro al grupo, se conforma un grupo compuesto por los miembros anteriores ms el nuevo miembro. En la capa de transporte no existe el concepto de sesin, sino que la comunicaciones entre dispositivos se dan por medio de grupos aislados de se conforman y disuelven en el transcurso a lo largo del tiempo. La capa de sesin introduce el concepto de sesin que se compone de una sucesin de grupos que integra un dispositivo. Cuando un dispositivo establece una sesin pasa a formar parte de un grupo determinado que finaliza su vida cuando cambia su composicin de miembros. Ocurrido sto ltimo, se forma un nuevo grupo al cual pertenecer automticamente el dispositivo, y sto ltimo seguir ocurriendo hasta que el dispositivo finalice la sesin. La finalizacin de la sesin implica la conformacin de un nuevo grupo sin el dispositivo que ha cerrado su sesin. Cada uno de stos grupos se denominan vistas [VerssimoRodrigues01], y en la capa de sesin, los grupos de difusin se conforman a partir de una sucesin de vistas.

Figura 4.23. Ejemplo de vistas [VerssimoRodrigues01].

Un dispositivo que ha iniciado una sesin puede fallar y encontrarse incomunicado en un determinado instante, lo que provoca la finalizacin de una vista y la creacin de otra sin el dispositivo en cuestin hasta que vuelva a reintegrarse conformndose nuevamente otra vista idntica a la inicial. sta situacin no se notificar a las capas superiores siempre y cuando la secuencia de los mensajes se mantenga (no se pierdan mensajes en secuencia). Los mensajes fuera de secuencia no son tenidos en cuenta, porque el inters en ellos slo se da en un instante determinado. En caso de haber prdidas de mensajes en secuencia, la sesin finaliza de forma forzada, debiendo la capa superior gestionar una nueva sesin como si el dispositivo ingresara por primera vez.

FernandoArielBeunza79156

133

Tesis de Grado en Ingeniera Informtica

4.5.2. Control del dilogo


La capa de sesin slo permite el flujo de informacin en un slo sentido: el publicador enva un mensaje hacia los suscriptores adheridos al grupo de difusin cuyo propietario es el publicador. ste tipo de comunicacin se denomina half duplex, y si es requiere de un flujo de informacin en ambos sentidos (full duplex), debe existir otro grupo de difusin que funcione en sentido inverso: el suscriptor debe pertenecer a un grupo de difusin en donde sea publicador, en el cual el publicador original sea suscriptor de ste ltimo grupo. De ste modo un dispositivo puede enviar una orden por medio de un mensaje, y el dispositivo destinatario de la orden puede responder a la misma; o el dispositivo destinatario para no estar esperando alguna instruccin, puede solicitarle al dispositivo origen que le de instrucciones para llevar a cabo alguna accin.

Figura 4.24. Ejemplo de dilogo entre dispositivos.

En la figura 4.24 se puede observar un ejemplo de las comunicaciones establecidas entre distintos dispositivos: mando de faros, control de faros, tablero de instrumentos y faros. Cuando se acciona el mando de faros se origina un mensaje por parte de ste dispositivo hacia el control de faros. El control de faros en respuesta al mensaje anterior enva un mensaje hacia los faros y el tablero de instrumentos. Como consecuencia de sto los faros se encienden y cada una de stos genera un mensaje de respuesta hacia el tablero de instrumentos indicando el estado de los faros (si se encendieron correctamente o alguno presenta algn desperfecto). El tablero de instrumentos recibe el mensaje proveniente del control de faros y de cada uno de los faros por separado, y genera como respuesta el encendido de un indicador del tablero de instrumentos y en caso de haber alguna falla genera una advertencia. ste ejemplo muestra la existencia de un grupo de difusin (1) cuyo publicador es el mando de faros y el suscriptor es el control de faros; ste ltimo a su vez es publicador de dos grupos de difusin (2 y 3) cuyos suscriptores son los faros y el tablero de instrumentos; y cada faro es publicador de un grupo de difusin (4, 5, 6 y 7) que posee un nico suscriptor que es el tablero de instrumentos.

4.5.3. Grupos de difusin


El grupo de difusin es medio por el cual un dispositivo intercambia informacin con otros mediante el pasaje de mensajes. Cada grupo se encuentra asociado a un grupo de difusin de la capa de transporte, en donde existen dispositivos que se suscriben y que publican mensajes. En el caso 134 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica particular del grupo de difusin se restringe a un dispositivo la capacidad de publicar (designado dispositivo publicador) y el resto son simples suscriptores destinatarios de los mensajes generados por el dispositivo anteriormente mencionado. Este concepto se asemeja a la idea de una red de cableado dedicado en donde un dispositivo genera una seal de salida que es tomada como entrada por otros dispositivos, en donde se puede establecer una analoga entre el primer dispositivo y el publicador, y el resto de los dispositivos y los suscriptores, siendo el conductor de la seal anlogo al grupo de difusin, y las seales encuentran su equivalente en los mensajes. Esta analoga permite trasladar un diseo de red implementado con cableado dedicado a la implementacin propuesta por la red PLC, en donde el cableado dedicado se implementa en forma virtual por medio de los grupos de difusin. Un grupo de difusin se individualiza del resto por medio del identificador nico. Cada uno de los dispositivos presentes en la red se asocian a dichos grupos en el momento en que se registran como publicadores o suscriptores en el inicio de la sesin, siendo este proceso anlogo a las conexiones fsicas de una red de cableado dedicado. El identificador de grupo es un nmero cuyo valor se encuentra comprendido entre 1 y 255. Cada dispositivo de la red puede ser publicador en varios grupos de difusin y a su vez suscriptores en otros grupos, permitiendo el flujo bidireccional de la informacin, conformando redes como por ejemplo la detallada en la figura 4.24. Dichas redes brindan la capacidad de ser expandidas agregando dispositivos con nuevas funcionalidades, por ejemplo se puede agregar un interruptor crepuscular simplemente agregando dos canales de difusin (figura 4.25): un canal en donde el mando de faros sea el publicador, y ordene la activacin o desactivacin del interruptor crepuscular que es el suscriptor, y otro canal en donde el interruptor crepuscular sea el publicador que ordene al control de faros (suscriptor) encender o apagar los faros y notificar al tablero de instrumentos de sta accin. La nica condicin que se exige para que sto sea posible es que el control de faros se registre al grupo de difusin en donde el interruptor crepuscular es publicador, independientemente de que se encuentre presente o no ste ltimo dispositivo, ya que pueden existir canales de difusin sin publicadores (aunque carezcan de sentido). sto permite disear un nico sistema con funcionalidades que se pueden agregar o quitar sin necesidad de realizar ningn cambio fsico sobre los dispositivos ms all de la conexin fsica de los mismos a la red.

Figura 4.25. Ejemplo de expansin de funcionalidades.

En la figura 4.25 se puede observar el agregado del interruptor crepuscular y el grupo de difusin utilizado para activarlo y desactivarlo (8), y el grupo de difusin que utiliza el interruptor crepuscular para ordenar al control de faros el encendido o apagado de los faros, y la notificacin al tablero de instrumentos (8). FernandoArielBeunza79156 135

Tesis de Grado en Ingeniera Informtica

4.5.4. Estructura de los mensajes


Los mensajes, adems de contener informacin, poseen cierta informacin adicional de control necesaria para que los dispositivos destinatarios puedan desarmarlos y recuperar la informacin originalmente enviada. A continuacin se detalla en la figura 4.26 la estructura de un mensaje:
Versin 8 bits 1 byte Datos (capacidad mxima de capa de transporte - 8) bits (capacidad mxima de capa de transporte - 1) bytes

Figura 4.26. Estructura de un mensaje.


Versin: identificador de versin del protocolo de transporte. Datos: informacin transportada por el mensaje. La mxima capacidad de transporte depende la capacidad que brinda la capa de transporte.

4.5.5. Primitivas de manejo de la capa de sesin


A continuacin se detallan las primitivas referentes al manejo de la capa de sesin (cuya implementacin se detalla en el Apndice C) que proporcionan las funcionalidades de inicializacin y liberacin de recursos, envo de mensajes y recepcin de los mismos:

void sp_init(void): Inicializa la capa de sesin, los buffers de mensajes y la funcin de recepcin de mensajes. void sp_release(void): Libera los recursos inicializados por la primitiva anterior. int sp_publish(sp_grpid grpid): Establece que el dispositivo es el publicador del grupo de difusin grpid. Si esta operacin se realiz correctamente y devuelve como resultado el valor uno, sino devuelve cero. int sp_subscribe(sp_grpid grpid): Establece que el dispositivo es suscriptor del grupo de difusin grpid. Si esta operacin se realiz correctamente y devuelve como resultado el valor uno, sino devuelve cero. int sp_leave(sp_grpid grpid): Desvincula el dispositivo del grupo de difusin grpid. Si esta operacin se realiz correctamente y devuelve como resultado el valor uno, sino devuelve cero. short int sp_send(sp_grpid grpid, unsigned char nosec, const void *msg, short int msgsize): FernandoArielBeunza79156

136

Tesis de Grado en Ingeniera Informtica Enva un mensaje msg de longitud msgsize del tipo type por medio del grupo de difusin grpid. El mensaje puede excluirse de la secuencia de mensajes enviados por medio de la activacin del indicador nosec, que en caso de una resincronizacin el mensaje no ser recuperado. Devuelve como resultado la cantidad de bytes enviados, que coincide con msgsize si la operacin de envo pudo ser realizada.

short int sp_receive(sp_grpid *grpid, void *msg, short int msgsize): Recibe msgsize bytes que se transfieren a msg recibido a travs del grupo de difusin grpid. Cuando se recibe un mensaje de la capa de transporte, se invoca la funcin dedicada a recepcin y procesamiento de mensajes. Si luego de interpretar el mensaje, ste resulta vlido, se almacena en el buffer de mensajes. Esta primitiva transfiere msgsize bytes del contenido del buffer a msg y devuelve la cantidad de bytes transferidos como resultado. Si el buffer se encuentra vaco, queda a la espera de que llegue un mensaje. void sp_notify(void (*func)(sp_grpid grpid, void *msg, short int msgsize)): Esta primitiva brinda la posibilidad de definir una funcin func que se ejecute cuando se recibe un mensaje por medio del grupo de difusin grpid. Dicha funcin debe tener definidos como parmetros grpid, msg y msgsize, que cumplen la misma funcin que en la primitiva de anterior. El objetivo de sta primitiva es poder procesar la informacin que transporta el mensaje de forma inmediata a la recepcin del mismo, sin bloquear el microcontrolador, como ocurre con la anterior primitiva. int sp_poll(void): Esta primitiva verifica el estado del buffer de mensajes. Devuelve como resultado uno si el buffer contiene un mensaje a la espera de ser recibido mediante la primitiva sp_receive. Si el buffer se encuentra vaco el resultado devuelto es cero. De sta forma puede implementarse una espera no bloqueante utilizando la primitiva sp_receive. int sp_status(void): Esta primitiva verifica si la conexin se encuentra activa o no. Una conexin queda inactiva cuando la capa de sesin no pudo resincronizar el dispositivo. Devuelve como resultado un valor positivo distinto a cero si el nodo se encuentra operativo. Si no hay ninguna interfaz fsica activa el resultado devuelto es cero. short int sp_getpayloadsize(void): Esta primitiva devuelve la cantidad mxima de bytes que puede contener un mensaje.

El conjunto de primitivas descripto abstrae en dos primitivas la inicializacin y liberacin de los recursos utilizados por la capa de sesin, en tres primitivas el registro y desvinculacin de un dispositivo a un determinado grupo de difusin, en cuatro primitivas el envo y recepcin (en modo bloqueante y no bloqueante) de mensajes, y en dos primitivas el manejo de informacin acerca del dispositivo.

FernandoArielBeunza79156

137

Tesis de Grado en Ingeniera Informtica

4.6. Capa de presentacin


La capa de presentacin es responsable de proveer los mecanismos para el transporte de datos estructurados entre diferentes aplicaciones usuarias. sto implica realizar las conversiones correspondientes segn la plataforma sobre la cual se montan las aplicaciones usuarias, para que stas ltimas procesen de forma correcta los datos recibidos (por ejemplo, la representacin de un entero utilizada en la plataforma Intel es diferente la utilizada en la plataforma Motorola). La capa de sesin solamente brinda la capacidad de transporte de datos sin ninguna estructura de forma confiable, siendo responsabilidad de la capa de presentacin la implementacin de un protocolo de representacin de cada tipo de datos independiente de las plataformas utilizadas en las aplicaciones usuarias, e implementar en stas ltimas los correspondientes mecanismos de conversin entre la representacin utilizada por el protocolo y la representacin propia de cada plataforma.

4.6.1. Implementacin de datos estructurados


Todas las capas tratadas hasta ahora trabajan con datos sin ningn tipo de estructura de organizacin, simplemente son cadenas de bytes cuya responsabilidad de interpretarlos de la forma correcta recae sobre la aplicacin usuaria que se encuentra por encima de la capa de sesin. Adems existe una dependencia proveniente de la plataforma, como ocurre con los valores enteros, que no toda las plataformas implementan este tipo de datos de la misma forma, por lo cual una aplicacin que corre sobre una plataforma Intel, cuando recibe un valor entero originado por otra aplicacin que corre sobre una plataforma Motorola, debe realizarse una conversin previa, ya que ambas plataformas representan los valores enteros de diferentes modos. La no realizacin de dicha conversin provocara un resultado errneo. Lo deseable en stos casos es de disponer de una capa de abstraccin que realice todas las conversiones necesarias cuando son necesarias y que la aplicacin usuaria se liber de sta tarea. La capa de presentacin se crea para brindar la abstraccin anteriormente mencionada. La introduccin de la capa de presentacin trae como consecuencia la necesidad de implementar un protocolo propio de representacin de un conjunto de tipos de datos que sea independiente de la plataforma donde corre especficamente la mencionada capa, por ejemplo, la capa de presentacin puede establecer que la forma de representar un valor entero sea compatible a la utilizada por la plataforma Motorola, en tal caso, la implementacin de la capa de presentacin sobre una plataforma compatible con Motorola, no modifica los valores enteros enviados o recibidos; en cambio si la capa de presentacin se encuentra implementada sobre una plataforma Intel siempre que se enve o reciba un valor entero debe realizarse la conversin correspondiente. Como se puede observar en el ejemplo anterior, la capa de presentacin es dependiente de la plataforma sobre la cual es implementada, por lo cual se requiere tantas versiones de dicha capa como plataformas se quiera cubrir. sto hace que la capa de presentacin no se encuentre implementada dentro de modem PLC, como ocurre con las capas inferiores a sta. Adems del tpico ejemplo de los valores enteros y sus distintas variantes (16 bits, 32 bits, etc.), existen otras estructuras de datos como valores de punto flotante y caracteres. stos tipos de datos son atmicos o simples, pero tambin existe la necesidad de combinarlos para conformar estructuras de datos ms complejas. Un ejemplo son los arreglos que pueden conformarse por varios valores enteros o de punto flotante; en el caso de los caracteres, un arreglo de ste tipo de dato conforma una cadena de caracteres. Adems de conformar una estructura compuesta por varios datos de un nico tipo, pueden existir estructuras conformadas por datos de distintos tipos e incluso arreglos de datos. Los diferentes tipos de datos y sus posibles combinaciones en estructuras 138 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica complejas deberan ir de la mano junto con el lenguaje de programacin cliente de la capa de presentacin para tener cubierta todas las posibilidades y poder armar mensajes con diferentes estructuras de datos. El estndar LonWorks es uno de los estndares existentes que resuelve el problema de la representacin de los datos implementando una capa de presentacin. La idea que propone es de disponer de un conjunto de tipos atmicos que se puedan combinar para formar tipos compuestos como arreglos y estructuras. En el presente trabajo se toma la misma idea de LonWorks, y se implementa una capa de presentacin con tipos de datos atmicos similares que pueden componer tipos compuestos. La capa de presentacin implementada en ste trabajo presenta hacia las capas superiores un conjunto de tipos de datos para ser usados independiente de la plataforma sobre la cual se est trabajando. sto implica que un tipo de datos brindado por la capa de presentacin debe ser posible su representacin en todas las plataformas. La idea de la presente capa es presentar un conjunto reducido de tipos de datos que permita por medio de combinaciones de los mismos poder representar un conjunto bsico de estructuras de datos. Los tipos de datos pueden ser atmicos (simples) o compuestos (integrados por tipos de datos atmicos o a su vez compuestos). Dentro de los tipos de datos atmicos, la capa de presentacin define los siguientes:

Caracter: representa un caracter. Enteros de 8 bits: representa un valor entero cuyo rango de valores posibles se encuentra comprendido entre -128 y 127 (en caso de ser enteros con signo) o entre 0 y 255 (en caso de tratarse de enteros sin signo). Enteros de 16 bits: representa un valor entero cuyo rango de valores posibles se encuentra comprendido entre -32768 y 32767 (en caso de ser enteros con signo) o entre 0 y 65535 (en caso de tratarse de enteros sin signo). Enteros de 32 bits: representa un valor entero cuyo rango de valores posibles se encuentra comprendido entre -2147483648 y 2147483647 (en caso de ser enteros con signo) o entre 0 y 4294697296 (en caso de tratarse de enteros sin signo). Punto flotante: representa un valor decimal cuyo rango de valores se encuentra comprendido aproximadamente entre 10-38 y 1038.

Los tipos de datos compuestos pueden ser arreglos, o estructuras que contengan tipos de datos atmicos o arreglos. Con cada uno los tipos de datos atmicos se pueden conformar arreglos de datos, para constituir, por ejemplo, una lista de valores enteros o de punto flotante. Con un arreglo del tipo caracter se puede construir una cadena de caracteres de suma para el envo mensajes con texto. A su vez se puede crear una estructura de datos compuesta por arreglos de tipos de datos atmicos. Una estructura adems de poder contener arreglos puede contener tipos de datos atmicos individuales. La implementacin de la capa de presentacin define el concepto de mensaje como un conjunto de campos de datos. A cada uno de stos campos se le puede especificar un tipo asociado al tipo de dato que se desea almacenar en el mismo. Adems se puede establecer la cantidad de datos almacenados, permitiendo la conformacin de arreglos de un determinado tipo de dato. De esta forma, un mensaje conforma una estructura de datos.

FernandoArielBeunza79156

139

Tesis de Grado en Ingeniera Informtica La capa de presentacin implementa una forma propia de representar cada uno de los tipos de datos anteriores que es independiente de la representacin utilizada por la plataforma. sto ltimo afecta a los tipos de datos atmicos, cuya representacin se describe a continuacin:

Caracter: se representa por medio de un byte. Enteros de 8 bits: se representa por medio de un byte. Enteros de 16 bits: se representa por medio de dos bytes con la disposicin big endian. Enteros de 32 bits: se representa por medio de cuatro bytes con la disposicin big endian. Punto flotante: se representa por medio de cuatro bytes conforme a lo especificado en el estndar 754 de IEEE [IEEE754] para representacin de nmeros decimales con simple precisin.

4.6.2. Esquema multiplataforma


Como se hizo mencin con anterioridad, la capa de presentacin debe ser multiplataforma, es decir que debe existir una implementacin por cada plataforma que se desee integrar al red PLC. Con las capas inferiores no es necesario sto ltimo, debido a que se encuentran implementadas dentro del modem PLC que responde a una nica plataforma, que en ste caso particular corresponde a los microcontroladores de la familia 8052. Por las razones expuestas con anterioridad, la capa de presentacin no puede implementarse dentro del modem PLC debido a que sta capa es dependiente de la plataforma, ya que las operaciones de conversin de datos deben realizarse conforme a la plataforma sobre la cual se monta sta capa. En el presente trabajo se utilizan tres plataformas: AT89X5X, Windows y Linux. La primer plataforma es necesaria para implementar dispositivos clientes reales con una funcin particular, que en ste caso se opta por utilizar microcontroladores de la familia 8051. La segunda y tercer plataforma se relacionan con los dispositivos clientes virtuales que se pueden simular con una PC y con el monitoreo de la red PLC. En referencia al hardware, para la segunda y tercer plataforma, es el mismo; la diferencia radica en el sistema operativo utilizado, que para este trabajo se utiliza Windows y Linux para mostrar la independencia de la red PLC respecto al sistema operativo que se utilice en la PC. La capa de presentacin junto con las capa inmediata superior (capa de aplicacin) y la interfaz de comunicacin con el modem PLC, se implementan dentro de una biblioteca esttica, para el caso de la plataforma AT89X5X, y de un driver y una biblioteca dinmica para el caso de Windows y Linux. La idea con esto es permitir un acceso simple a la red PLC por parte de las aplicaciones clientes utilizando un conjunto de rutinas idntico para todas las plataformas, aunque en realidad difieran en su implementacin interna. Tanto las plataforma AT89X5X, como Windows y Linux, todas son compatibles con arquitectura Intel, por lo cual a primera vista resulte innecesaria la existencia de una capa de presentacin, pero la idea del presente trabajo es dejar abierta la posibilidad de la incorporacin de nuevas plataformas ms all de las utilizadas para la evaluacin de la solucin propuesta, por ste motivo no se puede obviar la existencia de la capa de presentacin.

140

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

4.6.3. Estructura de los mensajes


Los mensajes se conforman de una sucesin de campos de datos, y cantidad y tamao de stos se encuentra limitada a la capacidad mxima de transporte que brinda la capa inmediata inferior (capa de sesin). Cada campo de datos representa a un tipo de dato diferente, permitiendo que un mensaje pueda formar una estructura de datos compleja. Adems por cada tipo de dato pueden tenerse uno o varios datos, lo que permite conformar arreglos de datos. A continuacin se detalla en la figura 4.27 la estructura de un campo de datos:
Tipo de Cantidad campo de datos 8 bits 1 byte 8 bits 1 byte Datos (tamao tipo de dato * cantidad de datos) bits (tamao tipo de dato * cantidad de datos) bytes

Figura 4.27. Estructura de un campo de datos.


Tipo de campo: especifica el tipo de datos almacenado en el rea de datos. Cantidad de datos: especifica la cantidad de datos almacenados en el rea de datos. Tiene un mximo terico de 256, pero el mximo real depende del tamao del tipo de dato y de la capacidad de transporte del mensaje. Datos: rea donde se almacenan el o los datos. La capacidad sta limitada por la capacidad mxima de transporte del mensaje.

4.6.4. Primitivas de manejo de la capa de presentacin


A continuacin se detallan las primitivas referentes al manejo de la capa de presentacin (cuya implementacin se detalla en el Apndice C) que proporcionan las funcionalidades de inicializacin y liberacin de recursos, envo de mensajes y recepcin de los mismos:

modplcpp_hd *modplcpp_init(int sid): Inicializa la capa de presentacin, la conexin con el modem PLC a travs de la interfaz de comunicacin serie sid. La interfaz de comunicacin serie se especifica por medio de un nmero identificatorio que en caso de la plataforma AT89X5X el nico valor posible es 1 (por existir solamente una interfaz), en caso de la plataforma Windows dicho nmero corresponde al puerto COM (el valor 1 equivale a COM1, el valor 2 equivale a COM2, etc.), y en caso de la plataforma Linux el nmero de puerto corresponde a la interfaz /dev/ ttyS (el valor 1 equivale a /dev/ttyS0, el valor 2 equivale a /dev/ttyS1, etc.). Si la operacin se realiz correctamente devuelve el manejador de conexin, sino devuelve un manejador nulo. int modplcpp_release(modplcpp_hd *hd): Libera los recursos de la capa de presentacin asociados al manejador de conexin hd. Si esta operacin se realiz correctamente y devuelve como resultado el valor uno, sino devuelve cero. int modplcpp_publish(modplcpp_hd *hd, modplcpp_grpid grpid): 141

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica Establece que el dispositivo es el publicador del grupo de difusin grpid, por medio de la conexin hd. Si esta operacin se realiz correctamente y devuelve como resultado el valor uno, sino devuelve cero.

int modplcpp_subscribe(modplcpp_hd *hd, modplcpp_grpid grpid): Establece que el dispositivo es suscriptor del grupo de difusin grpid por medio de la conexin hd. Si esta operacin se realiz correctamente y devuelve como resultado el valor uno, sino devuelve cero. int modplcpp_leave(modplcpp_hd *hd, modplcpp_grpid grpid): Desvincula el dispositivo del grupo de difusin grpid por medio de la conexin hd. Si esta operacin se realiz correctamente y devuelve como resultado el valor uno, sino devuelve cero. int modplcpp_newmsg(modplcpp_hd *hd, modplcpp_msg *msg, modplcpp_grpid grpid, modplcpp_mtype mtype): Crea un nuevo mensaje msg, del tipo mtype que ser enviado por el grupo de difusin grpid por medio de la conexin hd. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno y la estructura del mensaje inicializada lista para ser completada con diferentes campos, sino devuelve cero. int modplcpp_copymsg(modplcpp_msg *dest, modplcpp_msg *src): Crea una copia en dest del mensaje src. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno, sino devuelve cero. int modplcpp_putfield(modplcpp_msg *msg, modplcpp_ftype type, unsigned char count, const void *dat): Agrega un nuevo campo al mensaje msg. Dicho campo se compone de una cantidad count de datos dat del tipo ftype. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno y la estructura del mensaje con el nuevo campo incorporado, sino devuelve cero. int modplcpp_sendmsg(modplcpp_msg *msg): Enva un mensaje msg. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno, sino devuelve cero. int modplcpp_receivemsg(modplcpp_hd *hd, modplcpp_msg *msg): Recibe un mensaje msg por medio de la conexin hd. Si no existe ningn mensaje pendiente de ser recibido, queda a la espera de la llegada de uno. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno, sino devuelve cero. int modplcpp_getfield(modplcpp_msg *msg, modplcpp_ftype *type, unsigned char *count, void *dat): Extrae del mensaje msg un campo compuesto por una cantidad count de datos dat del tipo ftype. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno y la estructura del mensaje sin el campo extrado, sino devuelve cero. modplcpp_grpid modplcpp_getgrpid(modplcpp_msg *msg):

142

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica Extrae del mensaje msg el identificador de grupo de difusin por el cual fue recibido. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno, sino devuelve cero.

int modplcpp_destroymsg(modplcpp_msg *msg): Destruye el mensaje msg liberando todos los recursos utilizados por ste. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno, sino devuelve cero. int modplcpp_notify(modplcpp_hd *hd, void (*func)(modplcpp_hd *hd, modplcpp_msg *msg, void *param), void *param): Esta primitiva brinda la posibilidad de definir una funcin func que se ejecute cuando se recibe un mensaje. Dicha funcin debe tener definidos como parmetros hd, msg y param, que cumplen la misma funcin que en la primitiva modplcpp_receivemsg. El objetivo de sta primitiva es poder un mensaje de forma inmediata a la recepcin de la mismo, sin bloquear el microcontrolador. El parmetro param es opcional y puede ser utilizado para enviar parmetros adicionales al momento de invocar a la funcin func. int modplcpp_poll(modplcpp_hd *hd): Esta primitiva verifica si hay algn mensaje a la espera de ser recibido por medio de la conexin hd. Devuelve como resultado uno si existe un mensaje a la espera de ser recibido mediante la primitiva modplcpp_receivemsg. Caso contrario, el resultado devuelto es cero. De sta forma puede implementarse una espera no bloqueante utilizando la primitiva modplcpp_receivemsg. int modplcpp_status(modplcpp_hd *hd): Esta primitiva verifica si la conexin con modem PLC asociada al manejador hd se encuentra activa o no. Devuelve como resultado un valor positivo distinto a cero si el nodo se encuentra activo, caso contrario devuelve como resultado cero.

El conjunto de primitivas descripto abstrae en dos primitivas la inicializacin y liberacin de los recursos utilizados por la capa de presentacin, en tres primitivas la suscripcin y desvinculacin de un dispositivo a un determinado grupo de difusin, en diez primitivas el armado y desarmado de mensajes, y en una primitiva la verificacin del estado de la conexin.

4.7. Capa de aplicacin


La capa de aplicacin es responsable de proveer un servicio de intercambio de mensajes entre distintos dispositivos que pueden pertenecer a distintas plataformas, y que adems pueden ser reales o virtuales (dispositivos simulados por computadora). Dichos mensajes son utilizados para enviar rdenes solicitando la realizacin de acciones concretas por parte de los dispositivos destinatarios, o bien para modificar la configuracin de stos ltimos. Los mensajes tambin pueden ser utilizados para reportar estados o fallas de dispositivos.

FernandoArielBeunza79156

143

Tesis de Grado en Ingeniera Informtica

4.7.1. Servicio de mensajera


Los distintos dispositivos conectados a una red PLC comn es intercomunican por medio de un bus de mensajes a diferencia de las redes dedicadas que lo realizan por medio de seales que viajan por conductores dedicados. El concepto es simple, en una red dedicada se enva una seal para activar o desactivar algo, por ejemplo el encendido o apagado de un faro; en cambio en un bus de mensajes se transmite una orden de encendido o apagado que es ejecutada por el destinatario quien realiza la accin correspondiente. sto ltimo se puede observan en redes como CAN y J1850, aunque en las redes anteriores los mensajes se encuentran muy relacionados con el medio fsico. En cambio en las redes como LonWorks y MOST, el servicio de mensajera es ms independiente de los aspectos fsicos debido a que se implementa a nivel de capa de aplicacin. La idea de ste trabajo es seguir la propuestas de las dos ltimas redes mencionadas, debido a que en el presente trabajo se implementan las siete capas propuestas por el modelo OSI. La capa de presentacin permite el envo de mensajes estructurados en donde se pueden definir distintos tipos de datos independientes de la plataforma de trabajo. Con este servicio provisto se puede componer una orden conformada por un identificador propio del mismo y una serie de parmetros opcionales que pueden ser necesarios si la orden a transmitir requiere de una accin compleja, por ejemplo, si se requiere regular la intensidad lumnica de un dispositivo de iluminacin no bastar con una orden de encendido o apagado sino que debe pasarse como parmetro el valor asociado a la intensidad. Los mensajes que dan una orden son generados por los dispositivos clientes que solicitan la realizacin de una determinada accin y son recibidos por el o los dispositivos encargados de llevarla a cabo debido al esquema de difusin implementado por la pila de protocolos. La va es unidireccional ya que no brinda la posibilidad de respuesta en forma directa debido a que respuestas de mltiples destinatarios requiere una implementacin compleja. Igualmente se puede implementar un mecanismo de respuesta a la accin solicitada mediante otro mensaje en donde el destinatario original sea el generador de este mensaje de respuesta y el dispositivo que requiri la accin originariamente sea el destinatario. A su vez este mensaje de respuesta puede ser captado por otros dispositivos no involucrados con la orden original. Dicho mensaje de respuesta puede hacer uso de los parmetros para informar el estado de la accin ejecutada, por ejemplo si el dispositivo de iluminacin detecta que el foco se encuentra quemado puede reportar mediante un cdigo que la orden de regular la intensidad no se puede ejecutar por una falla del dispositivo en el iluminacin. Los mensajes adems de estar asociados a una orden o a una respuesta de sta, puede solicitar cambios en la configuracin de un dispositivo, por ejemplo el control de posicin de faros delanteros puede enviar un mensaje a los faros delanteros indicando modificar la posicin de los mismos ante un cambio realizado por el usuario por medio del control anterior. sto ltimo puede verse tambin como una orden, pero tiene diferencia con respecto, por ejemplo, el encendido o apagado de los faros. La diferencia radica en que cambiar una configuracin es un cambio persistente que no prioriza el tiempo necesario para realizarlo, por lo cual el sistema de comunicacin pone nfasis en asegurar que el mensaje llegue que en el tiempo que demor en realizar sto ltimo. El encendido o apagado de un faro requiere que la accin sea ejecutada lo ms rpido posible, resignando la persistencia a favor del tiempo real. En base a lo anterior, la implementacin propuesta establece dos tipos de mensajes: uno correspondiente para el primer caso estudiado y otro para el segundo. La manera de indicar el tipo de mensaje que se desea utilizar es por medio del identificador de mensaje en donde se establece que los identificadores menores al valor hexadecimal 8000 pertenecen al primer tipo, y los mayores al segundo tipo. Los parmetros de los mensaje trabajan con diferentes tipos de datos heredados de la capa inmediata inferior (capa de presentacin) lo que mantiene la independencia de plataforma y permite trabajar con tipos de datos ms complejos que el byte, por ejemplo la intensidad del foco de 144 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica iluminacin puede regularse en un rango comprendido entre 0 y 65535, lo cual requiere de un nmero entero de 16 bits; y por la independencia de plataforma el dispositivo que origin la orden podra ser un microcontrolador de la familia Motorola y el microcontrolador del dispositivo destinatario de la familia Intel sin ningn inconveniente. Tambin los parmetros pueden ser arreglos de tipos, en caso de tener que enviar varios parmetros del mismo tipo; y un mensaje puede presentar varios parmetros de diferentes tipos, del mismo modo que lo hacen los mensajes de la capa de presentacin. Los tipos de datos permitidos para los parmetros de los mensajes son idnticos a los provistos por la capa de presentacin (ver representacin de estructuras de datos).

4.7.2. Esquema multiplataforma


La capa de aplicacin se puede ver como la interfaz final de la pila de protocolos encargados del servicio de mensajera por medio de la red PLC. Dicha interfaz es nica para todas las plataformas, lo cual no significa que si lo sea su implementacin. De la misma manera que en la capa de presentacin, la capa de aplicacin implementa tres plataformas: AT89X5X, Windows y Linux. Las diferencias entre las distintas implementaciones se encuentran relacionadas con la forma de implementar las bibliotecas en cada una de las plataformas. Para el caso de la plataforma AT89X5X, la biblioteca es esttica y no requiere mayor complejidad que presentar la declaracin de cada una de las rutinas y la biblioteca con la implementacin de las mismas. Mencionadas rutinas se unen junto con las propias de la aplicacin cliente durante el proceso de compilacin para conformar un firmware que residir en un microcontrolador de la familia AT89X5X. Diferente es el caso de las plataformas Windows y Linux, ya que stos entornos son ms complejos que un microcontrolador. En ambos casos las bibliotecas no son estticas, sino dinmicas, lo que significa que las rutinas de la biblioteca y las rutinas propias de la aplicacin usuaria residen en forma separada y no se unen en el proceso de compilacin como ocurra con el anterior caso. A su ves estas dos ltimas plataformas tiene implementaciones diferentes de bibliotecas dinmicas: en Windows es necesario adicionar cdigo dedicado a la carga de las rutinas de la biblioteca, mientras que en Linux la operatoria es similar a la empleada cuando la biblioteca es esttica (afecta al proceso de compilacin, pero no el cdigo fuente). Las bibliotecas dinmicas no se comunican directamente con el modem PLC, sino que lo hacen por medio de un driver, que adems permite que varias aplicaciones puedan trabajar con un mismo modem compartiendo la conexin. La vista final en todos los casos es la misma, porque cada plataforma contiene el cdigo necesario para que la aplicacin usuaria se desentienda completamente del manejo de bibliotecas salvo del mtodo de invocacin de las mismas. De la misma manera como ocurre con la capa de presentacin, la presente capa a pesar de implementar solamente tres plataformas, es dejar abierta la posibilidad de la incorporacin de nuevas plataformas ms all de las utilizadas para la evaluacin de la solucin propuesta.

4.7.3. Primitivas de manejo de la capa de aplicacin


A continuacin se detallan las primitivas referentes al manejo de la capa de aplicacin (cuya implementacin se detalla en el Apndice C) que proporcionan las funcionalidades de inicializacin y liberacin de recursos, envo de mensajes y recepcin de los mismos:

FernandoArielBeunza79156

145

Tesis de Grado en Ingeniera Informtica

modplcap_hd *modplcap_init(int sid): Inicializa la capa de aplicacin, la conexin con el modem PLC a travs de la interfaz de comunicacin serie sid. La interfaz de comunicacin serie se especifica por medio de un nmero identificatorio que en caso de la plataforma AT89X5X el nico valor posible es 1 (por existir solamente una interfaz), en caso de la plataforma Windows dicho nmero corresponde al puerto COM (el valor 1 equivale a COM1, el valor 2 equivale a COM2, etc.), y en caso de la plataforma Linux el nmero de puerto corresponde a la interfaz /dev/ ttyS (el valor 1 equivale a /dev/ttyS0, el valor 2 equivale a /dev/ttyS1, etc.). Si la operacin se realiz correctamente devuelve el manejador de conexin, sino devuelve un manejador nulo. int modplcap_release(modplcap_hd *hd): Libera los recursos de la capa de aplicacin asociados al manejador de conexin hd. Si esta operacin se realiz correctamente y devuelve como resultado el valor uno, sino devuelve cero. int modplcap_publish(modplcap_hd *hd, modplcap_grpid grpid): Establece que el dispositivo es el publicador del grupo de difusin grpid, por medio de la conexin hd. Si esta operacin se realiz correctamente y devuelve como resultado el valor uno, sino devuelve cero. int modplcap_subscribe(modplcap_hd *hd, modplcap_grpid grpid): Establece que el dispositivo es suscriptor del grupo de difusin grpid por medio de la conexin hd. Si esta operacin se realiz correctamente y devuelve como resultado el valor uno, sino devuelve cero. int modplcap_leave(modplcap_hd *hd, modplcap_grpid grpid): Desvincula el dispositivo del grupo de difusin grpid por medio de la conexin hd. Si esta operacin se realiz correctamente y devuelve como resultado el valor uno, sino devuelve cero. int modplcap_newmsg(modplcap_hd *hd, modplcap_msg *msg, modplcap_grpid grpid, modplcap_msgid msgid): Crea un nuevo mensaje msg cuyo identificador es msgid que ser enviado por el grupo de difusin grpid por medio de la conexin hd. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno y la estructura del mensaje inicializada lista para ser completada con diferentes campos, sino devuelve cero. int modplcap_copymsg(modplcap_msg *dest, modplcap_msg *src): Crea una copia en dest del mensaje src. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno, sino devuelve cero. int modplcap_putfield(modplcap_msg *msg, modplcap_ftype type, unsigned char count, const void *dat): Agrega un nuevo campo al mensaje msg. Dicho campo se compone de una cantidad count de datos dat del tipo ftype. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno y la estructura del mensaje con el nuevo campo incorporado, sino devuelve cero.

146

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

int modplcap_sendmsg(modplcap_msg *msg): Enva un mensaje msg. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno, sino devuelve cero. int modplcap_receivemsg(modplcap_hd *hd, modplcap_msg *msg): Recibe un mensaje msg por medio de la conexin hd. Si no existe ningn mensaje pendiente de ser recibido, queda a la espera de la llegada de uno. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno, sino devuelve cero. int modplcap_getfield(modplcap_msg *msg, modplcap_ftype *type, unsigned char *count, void *dat): Extrae del mensaje msg un campo compuesto por una cantidad count de datos dat del tipo ftype. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno y la estructura del mensaje sin el campo extrado, sino devuelve cero. modplcap_grpid modplcap_getgrpid(modplcap_msg *msg): Extrae del mensaje msg el identificador de grupo de difusin por el cual fue recibido. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno, sino devuelve cero. modplcap_msgid modplcap_getmsgid(modplcap_msg *msg): Extrae del mensaje msg el identificador del mismo. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno, sino devuelve cero. int modplcap_destroymsg(modplcap_msg *msg): Destruye el mensaje msg liberando todos los recursos utilizados por ste. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno, sino devuelve cero. int modplcap_notify(modplcap_hd *hd, void (*func)(modplcap_hd *hd, modplcap_msg *msg, void *param), void *param): Esta primitiva brinda la posibilidad de definir una funcin func que se ejecute cuando se recibe un mensaje. Dicha funcin debe tener definidos como parmetros hd, msg y param, que cumplen la misma funcin que en la primitiva modplcap_receivemsg. El objetivo de sta primitiva es poder un mensaje de forma inmediata a la recepcin de la mismo, sin bloquear el microcontrolador. El parmetro param es opcional y puede ser utilizado para enviar parmetros adicionales al momento de invocar a la funcin func. int modplcap_poll(modplcap_hd *hd): Esta primitiva verifica si hay algn mensaje a la espera de ser recibido por medio de la conexin hd. Devuelve como resultado uno si existe un mensaje a la espera de ser recibido mediante la primitiva modplcap_receivemsg. Caso contrario, el resultado devuelto es cero. De sta forma puede implementarse una espera no bloqueante utilizando la primitiva modplcap_receivemsg. int modplcap_status(modplcap_hd *hd): Esta primitiva verifica si la conexin con modem PLC asociada al manejador hd se encuentra activa o no. Devuelve como resultado un valor positivo distinto a cero si el nodo se encuentra activo, caso contrario devuelve como resultado cero. 147

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica El conjunto de primitivas descripto abstrae en dos primitivas la inicializacin y liberacin de los recursos utilizados por la capa de presentacin, en tres primitivas la suscripcin y desvinculacin de un dispositivo a un determinado grupo de difusin, en once primitivas el armado y desarmado de mensajes, y en una primitiva la verificacin del estado de la conexin.

4.7.4. Interfaz C++


Las primitivas mencionadas anteriormente resultan tiles para el desarrollo de aplicaciones en lenguaje C necesiten hacer uso del servicio de comunicaciones provisto por el sistema desarrollado. Un aspecto positivo en el diseo del sistema propuesto en ste trabajo es la flexibilidad para el agregado de extensiones que implementen interfaces para distintos entornos. Para demostrar sto ltimo, en el presente trabajo se propone una interfaz para lenguaje C++, que permite a aplicaciones desarrolladas en ste ltimo lenguaje, utilizar los servicios de comunicacin provistos por el sistema desarrollado. La interfaz C++ se compone de dos clases (cuya implementacin se detalla en el Apndice D): una que maneja la conexin con el modem PLC, y la otra dedicada a los mensajes enviados y recibidos por medio de la anterior. A continuacin se detallan los mtodos que componen a la primer clase mencionada referente al manejo de la conexin con el modem PLC:

modplcapcpp::modplcapcpp(int sid): Inicializa la capa de aplicacin, la conexin con el modem PLC a travs de la interfaz de comunicacin serie sid. La interfaz de comunicacin serie se especifica por medio de un nmero identificatorio que en caso de la plataforma Windows dicho nmero corresponde al puerto COM (el valor 1 equivale a COM1, el valor 2 equivale a COM2, etc.), y en caso de la plataforma Linux el nmero de puerto corresponde a la interfaz /dev/ttyS (el valor 1 equivale a /dev/ttyS0, el valor 2 equivale a /dev/ttyS1, etc.). Si la operacin se realiz correctamente devuelve un nuevo objeto conexin. modplcapcpp::~ modplcapcpp(): Libera los recursos de la capa de aplicacin asociados al objeto conexin. int modplcapcpp::publish(modplcap_grpid grpid): Establece que el dispositivo es el publicador del grupo de difusin grpid. Si esta operacin se realiz correctamente y devuelve como resultado el valor uno, sino devuelve cero. int modplcapcpp::subscribe(modplcap_grpid grpid): Establece que el dispositivo es suscriptor del grupo de difusin grpid. Si esta operacin se realiz correctamente y devuelve como resultado el valor uno, sino devuelve cero. int modplcapcpp::leave(modplcap_grpid grpid): Desvincula el dispositivo del grupo de difusin grpid. Si esta operacin se realiz correctamente y devuelve como resultado el valor uno, sino devuelve cero. int modplcapcpp::poll(void):

148

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica Esta primitiva verifica si hay algn mensaje a la espera de ser recibido. Devuelve como resultado uno si existe un mensaje a la espera de ser recibido. Caso contrario, el resultado devuelto es cero.

int modplcapcpp::status(void): Esta primitiva verifica si la conexin con modem PLC se encuentra activa o no. Devuelve como resultado un valor positivo distinto a cero si el nodo se encuentra activo, caso contrario devuelve como resultado cero.

De la misma forma que se detallaron los mtodos de la anterior clase, a continuacin se describen los mtodos que conforman a la clase que maneja los mensajes:

modplcapcpp_msg::modplcapcpp_msg(modplcapcpp *hd, modplcapcpp_grpid grpid, modplcapcpp_msgid msgid): Crea un nuevo mensaje cuyo identificador es msgid que ser enviado por el grupo de difusin grpid por medio de la conexin hd. Si esta operacin se realiz correctamente, el objeto mensaje se encuentra listo para ser completado con diferentes campos. modplcapcpp_msg::modplcapcpp_msg(modplcapcpp_msg *msg): Crea una copia del mensaje msg. Si esta operacin se realiz correctamente, un nuevo objeto mensaje que es una copia del mensaje msg. modplcapcpp_msg::modplcapcpp_msg(modplcapcpp *hd): Recibe un mensaje por medio de la conexin hd. Si no existe ningn mensaje pendiente de ser recibido, queda a la espera de la llegada de uno. Si esta operacin se realiz correctamente, devuelve como resultado un objeto mensaje con la informacin recibida. modplcapcpp_msg::~modplcapcpp_msg(): Destruye el mensaje liberando todos los recursos utilizados por ste. int modplcapcpp_msg::putfield(modplcapcpp_ftype type, unsigned char count, const void *dat): Agrega un nuevo campo al mensaje. Dicho campo se compone de una cantidad count de datos dat del tipo ftype. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno y la estructura del mensaje con el nuevo campo incorporado, sino devuelve cero. int modplcapcpp_msg::sendmsg(void): Enva un mensaje. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno, sino devuelve cero. int modplcapcpp_msg::getfield(modplcapcpp_ftype *type, unsigned char *count, void *dat): Extrae del mensaje un campo compuesto por una cantidad count de datos dat del tipo ftype. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno y la estructura del mensaje sin el campo extrado, sino devuelve cero. modplcapcpp_grpid modplcapcpp_msg::getgrpid(void):

FernandoArielBeunza79156

149

Tesis de Grado en Ingeniera Informtica Extrae del mensaje, el identificador de grupo de difusin por el cual fue recibido. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno, sino devuelve cero.

modplcapcpp_msgid modplcapcpp_msg::getmsgid(void): Extrae del mensaje, el identificador del mismo. Si esta operacin se realiz correctamente, devuelve como resultado el valor uno, sino devuelve cero.

4.7.5. Biblioteca de bloques Simulink


Las primitivas mencionadas anteriormente resultan cmodas a quienes se encuentran familiarizados con entornos de programacin, permitiendo desarrollar fcilmente aplicaciones clientes por medio de la especificacin de algoritmos en lenguaje C/C++. Adems el tener disponibles varias plataformas, entre las cuales figura Windows y Linux, permite al desarrollador de aplicaciones clientes poder confeccionar algoritmos y probarlos con una computadora personal, sin la necesidad de construir primero el hardware asociado a la aplicacin cliente. Pero estas ventajas solamente son aprovechadas por quienes tiene conocimientos de programacin, excluyendo a quienes tienen conocimientos sobre el desarrollo de aplicaciones clientes que no tengan dichos conocimientos de programacin. Para stos ltimos se les ofrece la posibilidad de interactuar con el modem PLC por medio de una interfaz grfica ms amigable que un conjunto de primitivas, dicha interfaz se encuentra diseada para la aplicacin Simulink suministrada dentro del conjunto de aplicaciones que provee MATLAB. El entorno Simulink brinda una forma fcil y rpida de modelar sistemas de control y evaluar su desempeo sin la necesidad de tener conocimientos de programacin. Simulink provee un variado conjunto de bibliotecas de bloques funcionales. La interfaz desarrollada en el presente trabajo pretende agregar a todas las funcionalidades provistas por Simulink la posibilidad de manipular el modem PLC de tal forma que se pueda modelar una aplicacin cliente con las funcionalidades nativas de Simulink y adems dicha aplicacin pueda hacer uso de la red PLC. La interfaz Simulink es de gran utilidad para el desarrollo de una primera versin de una aplicacin cliente, en la cual el inters se centra en desarrollar un modelo que cumpla con las funcionalidades requeridas, para luego pasar a la construccin ms eficiente de ste por medio de un algoritmo especificado mediante un lenguaje de programacin, y finalmente el desarrollo del hardware prototipo con el firmware que implementa el algoritmo anteriormente mencionado. Los detalles de la biblioteca de bloques funcionales Simulink referentes al manejo del modem PLC se describen en el Apndice E.

150

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

5. Evaluacin de la solucin propuesta


La evaluacin de la solucin propuesta por el presente trabajo consiste en comparar el sistema construido en base a los requerimientos planteados en el captulo 3, con los antecedentes existentes sobre tecnologa PLC y redes de datos para automviles. De sta forma se puede determinar el grado de xito logrado con la propuesta presentada, y determinar las diferencias y similitudes que presenta sta ltima en relacin a las alternativas existentes.

5.1. Comparacin con redes PLC para automviles


Aqu se procede a evaluar la solucin propuesta frente a los antecedentes sobre redes PLC para automviles utilizados como base para el desarrollo del prototipo propuesto por ste trabajo. Primero se evala el funcionamiento de las distintas partes del hardware que constituye al modem PLC; mdulo analgico y mdulo de procesamiento de seales. La evaluacin tambin incluye las caractersticas del canal de comunicacin utilizado. Una vez determinado el desempeo del hardware del modem PLC, se compara ste ltimo con las soluciones propuestas por los antecedentes que tratan el tema de las redes PLC en el ambiente de automviles.

5.1.1. Evaluacin del mdulo analgico


La primer parte que se evala del hardware constitutivo del modem PLC, es el mdulo analgico, parte ms ligada al canal de comunicacin. La evaluacin consta de simulaciones realizadas al mencionado mdulo (cuya implementacin se detallan en el Apndice B), y de mediciones sobre la implementacin real (detallada en el Apndice A). Las diferencias entre implementaciones se debe a que es necesarios cambiar algunos componentes, ya que existen diferencias de comportamiento entre los componentes simulados y los reales. A continuacin se describen una serie de situaciones a las cuales se somete el mdulo analgico simulado:

Situacin 1: Seal transmitida por medio de la lnea de potencia. La seal es la resultante de la modulacin de una seal de prueba compuesta por cinco componentes de frecuencia de 500 KHz, 1 MHz, 1,5 MHz, 2 MHz y 2,5 MHz; que cubren el rango de frecuencias permitido para la seal de entrada al transmisor. Situacin 2: Espectro de la seal transmitida por medio de la lnea de potencia. Muestra el espectro de la seal transmitida a travs de la lnea de potencia. Dicho espectro muestra las cinco componentes de la seal de prueba replicados por emplearse modulacin VSBSC. Situacin 3: Seal enviada y seal recibida. Muestra la seal de entrada al transmisor y la seal recibida a la salida del receptor. Ambas seales corresponden a la seal de prueba mencionada con anterioridad.

FernandoArielBeunza79156

151

Tesis de Grado en Ingeniera Informtica

Situacin 4: Espectro de la seal enviada y seal recibida. Muestra el espectro de la seal de entrada al transmisor y la seal recibida a la salida del receptor. Se puede observar las cinco componentes de frecuencia de la seal de prueba y la atenuacin de cada una de ellas a la salida del receptor. Situacin 5: Seal transmitida por medio de la lnea de potencia. En este caso se utiliza la seal smbolo utilizada para transmitir informacin. Situacin 6: Espectro de la seal transmitida por medio de la lnea de potencia. Muestra el espectro de la seal anterior transmitida a travs de la lnea de potencia. Situacin 7: Seal enviada y seal recibida. Muestra la seal smbolo de entrada al transmisor y la seal smbolo recibida a la salida del receptor. Situacin 8: Espectro de la seal enviada y seal recibida. Muestra el espectro de la seal smbolo de entrada al transmisor y la seal smbolo recibida a la salida del receptor.

El comportamiento del mdulo analgico frente a las situaciones planteadas con anterioridad se puede observar en los grficos que se encuentran a continuacin (en el mismo orden en el que se enumeraron cada una de las situaciones).

152

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

153

Tesis de Grado en Ingeniera Informtica

154

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

155

Tesis de Grado en Ingeniera Informtica

156

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

157

Tesis de Grado en Ingeniera Informtica

158

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

159

Tesis de Grado en Ingeniera Informtica

160

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica Los grficos anteriores muestran la respuesta en frecuencia que presenta el mdulo analgico. Se puede destacar como regin crtica la comprendida en la proximidad a los 16 MHz, donde el filtro presenta su mayor selectividad para poder eliminar la mayor parte de la banda superior, como corresponde a un esquema de modulacin VSB. Para evaluar el comportamiento del mdulo analgico implementado en la realidad, se eligen dos seales de frecuencia 138,237 KHz y 552,947 KHz, con el objeto de poder ver la respuesta en frecuencia de la regin crtica mencionada con anterioridad. Las pruebas se realizaron con dos modems (uno designado con la letra A y el otro con la letra B), la seal de prueba corresponde a la entrada del transmisor de uno de los modems y la seal de respuesta corresponde a la salida del receptor del otro modem, de sta forma en la prueba se incluyen todos los factores que pueden influenciar en la respuesta en frecuencia (ancho de banda del transmisor y receptor, canal de comunicacin, etc.). Las seales de prueba se generaron con el mdulo de procesamiento de seales, que implementa la funcionalidad de generar seales de prueba. En las figura 5.1 se puede observar la seal a la entrada del transmisor del mdulo analgico correspondiente al modem PLC designado con la letra A (transmisor), y en la figura 5.2 se puede ver la seal de respuesta a la salida del receptor del mdulo analgico correspondiente al modem PLC designado con la letra B (receptor).

Figura 5.1. Portadora de 138,237 KHz transmitida por A.

Figura 5.2. Portadora de 138,237KHz recibida por B.

Comparando las figuras anteriores, se puede observar el filtrado a alta frecuencia, ya que como se puede ver la seal de prueba presenta imperfecciones correspondientes a componentes de alta frecuencia, que no se observan en la seal de respuesta. Tambin se puede observar un atenuacin en la seal de respuesta en comparacin a la seal de prueba. Ambas seales deberan ser seales senoidales perfectas, pero en el caso de la seal de prueba no es as debido al mtodo que se utiliza para generarla produce ruido de alta frecuencia, y en el caso de la seal de respuesta se debe al sistema de modulacin VSB que agrega distorsin a baja frecuencia. Similar prueba realizada con la seal de prueba de 138,237 KHz se realiza con la seal de 552,947 KHz, cuyos resultados se reflejan en las figuras 5.3 y 5.4.

FernandoArielBeunza79156

161

Tesis de Grado en Ingeniera Informtica

Figura 5.3. Portadora de 552,947 KHz transmitida por A.

Figura 5.4. Portadora de 552,947 KHz recibida por B.

A diferencia de la prueba anterior, aqu se puede observa menor distorsin, y que prcticamente no existe atenuacin, ya que la frecuencia de la seal de prueba utilizada se encuentra fuera de la regin crtica. A continuacin se realizan las mismas pruebas anteriores, pero intercambiando las funcionalidades de los modems (el que anteriormente transmita ahora recibe, y el que reciba ahora transmite). Los resultados de la prueba con una seal de 138,237 KHz se pueden observar en las figuras 5.5 y 5.6:

Figura 5.5. Portadora de 138,237 KHz transmitida por B.

Figura 5.6. Portadora de 138,237KHz recibida por A.

El resultado obtenido es similar al de la prueba anterior, lo que indica que ambos transmisores y receptores, se comportan de similar forma. Tambin se repite la prueba con la seal de 552,947 KHz, cuyo resultado se puede ver en las figuras 5.7 y 5.8.

162

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Figura 5.7. Portadora de 552,947 KHz transmitida por B.

Figura 5.8. Portadora de 552,947 KHz recibida por A.

En este caso tambin el resultado es similar a la prueba anterior, por lo cual se puede concluir que ambos mdulos analgicos presentan respuesta en frecuencia similar, a pesar de las diferencias que puede contener cada uno de ellos debido a que los componentes no son idnticos. A partir de sta ltima conclusin, se puede elegir uno de los modems y observar la seal que genera ste cuando transmite informacin (en este caso se utiliza una secuencia pseudoaleatoria de bits como trama de prueba). En las figuras 5.9 y 5.10 se pueden observar la seal generada por el modem a la entrada del mdulo analgico y la seal recibida a la salida del mismo mdulo, respectivamente.

Figura 5.9. Seal transmitida y su espectro.

Figura 5.10. Seal recibida y su espectro.

En la figura 5.9 se puede distinguir claramente el espectro conformado por todas las portadoras constituyentes del smbolo utilizado para transmitir la informacin cuyo ancho de banda es de 2,7648 MHz. En cambio, en la figura 5.10, producto del ruido y la atenuacin de la lnea de potencia, no se distingue tan claramente la seal recibida, como en el caso de la figura anterior. sto ltimo tambin se puede observar en las siguientes figuras, donde se muestra el espectro de la seal observado en la lnea de potencia. FernandoArielBeunza79156 163

Tesis de Grado en Ingeniera Informtica

Figura 5.11. Seal presente en la entrada de alimentacin del modem PLC.

Figura 5.12. Seal presente en la lnea de potencia.

En la figura 5.11 se puede apreciar la misma seal de la figura 5.9 desplazada en frecuencia por el modulador del mdulo analgico. Lo observado corresponde a la seal presente a la entrada de alimentacin del modem PLC. La figura 5.12 corresponde a la misma seal, pero presente a una distancia de 1,5 metros del modem. Como era de esperar, sta ltima seal se observa ms atenuada que la primera y con una presencia de mayor nivel de ruido; pero en ambas figuras se puede distinguir que el espectro de la seal corresponde al de una modulacin VSB-SC, donde la banda vestigio se encuentra por encima de los 16 MHz, con un ancho de banda levemente mayor a 2,5 MHz. Comparando las mediciones con las simulaciones, se puede observar que el comportamiento de la implementacin real del mdulo analgico era el esperado, sin tener en cuenta el ruido y la atenuacin que no se encontraron presentes en las simulaciones.

5.1.2. Evaluacin del mdulo de procesamiento de seales


La segunda parte que se evala del hardware constitutivo del modem PLC, es el mdulo de procesamiento de seales; parte encargada de la modulacin y demodulacin, y del armado y desarmado de tramas de bits. La evaluacin consta de simulaciones realizadas al mencionado mdulo (cuya implementacin se detallan en el Apndice B), y de mediciones realizadas sobre la implementacin real (detallada en el Apndice A). Las diferencias entre implementaciones se debe al mismo motivo planteado cuando se trat el tema del mdulo analgico. A continuacin se describen las situaciones a las cuales se somete el mdulo de procesamiento de seales:

Situacin 1: Trama de bits transmitida y recibida. La trama de bits consta de un patrn de bits que muestra la correcta deteccin del valor de cada bit. En dicho patrn se muestra cambios frecuentes en el valor del bit (al comienzo de la trama) y cambios aislados (al final de la trama). Tambin se puede observar la trama de bits obtenida a la salida del integrador a partir de la seal obtenida del amplificador de salida.

164

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Situacin 2: Espectro de la seal obtenida del amplificador de salida. Muestra el espectro de la seal generada a partir de la trama de bits suministrada. Dicho espectro muestra el rango de frecuencias ocupado por las portadoras que conforman el smbolo utilizado para transmitir los bits de la trama.

FernandoArielBeunza79156

165

Tesis de Grado en Ingeniera Informtica

166

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

167

Tesis de Grado en Ingeniera Informtica En los grficos anteriores se pueden observar una trama de bits asociada una la seal de informacin generada por el mdulo de procesamiento de seales, en donde claramente se pueden diferenciar los valores de los bits de la trama. A continuacin se muestran dos tramas de bits generadas y recibidas por los mdulos de procesamiento de seales implementados en la realidad. La prueba se realiza en ambos sentidos, el modem A transmitiendo y el modem B recibiendo, y viceversa.

Figura 5.13. Trama de bits transmitida por A recibida por B.

Figura 5.14. Trama de bits transmitida por B recibida por A.

En las figuras 5.13 y 5.14, se pueden distinguir tambin los valores de los bits que conforman la trama. Los niveles de tensin bajos corresponden a bits de valor uno y los niveles de tensin altos corresponden a bits de valor cero. Se puede observan en ambas figuras que la trama comienza en un nivel alto correspondiente a la presencia de seal de informacin, seguido a un espacio correspondiente a una serie de bits de valor uno, luego se ve un nuevo pico utilizado para marcar el comienzo de una trama, seguido de un espacio previo a una secuencia de bits cero y uno, utilizada para ajuste del umbral de deteccin, seguido de un espacio, un delimitador y finalmente la informacin que corresponde a un byte de valor 01. Por ltimo un espacio y un pico que indica la ausencia de seal de informacin. En ambas figuras se puede observar que ambos mdulos de procesamiento de seales se comportan de forma similar transmitiendo y recibiendo tramas de bits, a pesar de que los componentes que constituyen cada uno de los mdulos no son idnticos (como ocurre con el mdulo analgico).

5.1.3. Evaluacin del canal de comunicacin


Ya habiendo evaluado el comportamiento de los mdulos analgicos y los mdulos de procesamiento de seales, y conociendo su comportamiento, se procede a evaluar el canal de comunicacin utilizado, que en este caso en la red de potencia conformado bsicamente de un par de cables comunes que se utilizan para alimentar los modems PLC, y por los cuales tambin se transporta informacin. La red de potencia utilizada para la realizacin de las pruebas consta de una fuente de alimentacin que provee tensin constante de 12V, conectada a un filtro constituido por un inductor 168 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica de 2.2uH, un tramo de cable doble (positivo y negativo), uno de los modems PLC, otro tramo de cable, y el otro modem PLC. Las pruebas consisten de observar el comportamiento de los modems variando la ubicacin y el largo del tramo de cable que los separa. El comportamiento de los modems se evala generando una serie de tramas de contenido y tamao aleatorio, envindolas por uno de los modems y recibiendo la misma trama por el otro modem, y comparando la trama enviada con la recibida; para observar la cantidad de bits que se pierden, que se reciben con error, as como tambin las tramas que se pierden y que se reciben pero deben ser descartadas porque presentan algn bit errado. A continuacin se presenta la primer configuracin de red, que se puede observar en la figura 5.15, en donde el largo del tramo de cable que une el filtro con el Modem PLC designado con la letra A, denominado D1, es de 1,5 metros, y el tramo de cable que une el Modem PLC A con el Modem PLC B, denominado D2, vara su longitud.

Figura 5.15. Esquema de prueba (Modem PLC A ms cerca del filtro).

Con la configuracin de la figura anterior, se realizan envos de tramas en ambos sentidos, del modem A al B y viceversa, con diferentes longitudes de cable, y tipo de cable comn como el utilizado para alimentacin. Los resultados pueden observarse en la tabla 5.1.

FernandoArielBeunza79156

169

Tesis de Grado en Ingeniera Informtica

D2 = 1,5 metros AB Bits enviados Bits perdidos % Bits perdidos Bits errneos % Bits errneos Tramas enviados Tramas perdidas % Tramas perdidas Tramas errneas % Tramas errneas 417456 35440 8,490% 2639 0,632% 250 23 9,200% 122 48,000% BA 386024 40352 10,453% 3163 0,819% 250 25 10,000% 40 16,000%

D2 = 10 metros AB 402016 40592 10,097% 2048 0,509% 250 27 10,800% 65 26,000% BA 419864 47448 11,301% 1520 0,362% 250 29 11,600% 59 23,600%

D2 = 20 metros AB 399144 102840 25,765% 5010 1,255% 250 66 26,400% 62 24,800% BA 426624 135536 31,769% 5719 1,341% 250 80 32,000% 61 24,400%

D2 = 30 metros AB 388544 94048 24,205% 4655 1,198% 250 66 26,400% 121 48,400% BA 395672 53480 13,519% 3097 0,783% 250 37 14,800% 91 36,400%

Tabla 5.1. Tasa de prdida y error segn el largo del cable utilizado para la configuracin propuesta en la figura 5.15.

Se puede concluir que el comportamiento de los modems va empeorando a medida que se aumenta la longitud del cable registrando un pico cuando se trabaja con una de longitud de 20 metros. Desde el punto de vista del sentido de la transmisin de las tramas, existen diferencias atribuibles a que los modems no son idnticos y dichas diferencias aumentan a medida que aumenta la longitud del cable. En la tabla 5.2, se muestra el comportamiento promedio para cada una de las longitudes de prueba:
D2 = 1,5 metros D2 = 10 metros D2 = 20 metros D2 = 30 metros % Bits perdidos % Bits errneos % Tramas perdidas % Tramas errneas 9,472% 0,726% 9,600% 32,000% 10,699% 0,436% 11,200% 24,800% 28,767% 1,298% 29,200% 24,600% 18,862% 0,991% 20,600% 42,400%

Tabla 5.2. Tasa promedio de prdida y error segn el largo del cable utilizado para la configuracin para la configuracin propuesta en la figura 5.15.

El comportamiento promedio marca de igual modo que la tabla 5.1 que el desempeo de los modems empeora con el aumento de la longitud del cable registrando un pico en 20 metros. A continuacin se evala el comportamiento segn el tipo de cable, fijando una longitud D2 en 5 metros. Para la prueba se utiliza cable comn y cable coaxil, ste ltimo mucho ms inmune a ruido que el primero, para ver cuanta influencia tiene el ruido en el empeoramiento anteriormente visto. 170 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Cable comn AB Bits enviados Bits perdidos % Bits perdidos Bits errneos % Bits errneos Tramas enviados Tramas perdidas % Tramas perdidas Tramas errneas % Tramas errneas 418552 77744 18,575% 3356 0,802% 250 44 17,600% 68 27,200% BA 402536 79136 19,659% 1051 0,261% 250 49 19,600% 53 21,200%

Cable coaxil AB 393904 38488 9,771% 4239 1,076% 250 22 8,800% 72 28,800% BA 397848 48664 12,232% 1549 0,389% 250 32 12,800% 61 24,400%

Tabla 5.3. Tasa de prdida y error segn el tipo de cable utilizado para la configuracin propuesta en la figura 5.15.

En la tabla anterior se puede observar que el ruido inducido en la lnea es un factor importante ya que el desempeo de los modems mejora notablemente cuando el tramo de cable utilizado es coaxil. Tambin se pueden ver diferencias segn el sentido de la transmisin, que no son demasiadas debido a que la longitud no es muy grande, y sto responde a la expuesto anteriormente a que los modems no son idnticos. De similar forma que se realiz en las anteriores pruebas, se obtiene el comportamiento promedio, como se puede observar en la tabla 5.4:
Cable comn Cable coaxil % Bits perdidos % Bits errneos % Tramas perdidas % Tramas errneas 19,117% 0,532% 18,600% 24,200% 11,002% 0,733% 10,800% 26,600%

Tabla 5.4. Tasa promedio de prdida y error segn el tipo de cable utilizado para la configuracin propuesta en la figura 5.15.

Aqu tambin de forma mucho ms clara puede observarse la mejora que existe al utilizar cable coaxil, destacando como factor importante el ruido inducido en la lnea de potencia. A continuacin se presenta una segunda configuracin de red, que se puede observar en la figura 5.16, similar a la utilizada anteriormente, pero cambiando la disposicin de los modems.

FernandoArielBeunza79156

171

Tesis de Grado en Ingeniera Informtica

Figura 5.16. Esquema de prueba (Modem PLC B ms cerca del filtro).

Con sta configuracin, se realizaron envos de tramas en ambos sentidos, variando la longitud de cable, y utilizando tipo de cable comn. Los resultados pueden observarse en la tabla 5.5 que se detalla a continuacin:
D2 = 1,5 metros AB Bits enviados Bits perdidos % Bits perdidos Bits errneos % Bits errneos Tramas enviados Tramas perdidas % Tramas perdidas Tramas errneas % Tramas errneas 401344 45408 11,314% 5183 1,291% 250 25 10,000% 108 43,200% BA 405976 32160 7,922% 4422 1,089% 250 22 8,800% 34 13,600% D2 = 10 metros AB 383784 59848 15,594% 2083 0,543% 250 38 15,200% 68 27,200% BA 416048 50712 12,189% 2609 0,627% 250 29 11,600% 57 22,800% D2 = 20 metros AB 367512 115408 31,403% 4057 1,104% 250 85 34,000% 73 29,200% BA 407312 118640 29,128% 6509 1,598% 250 77 30,000% 46 18,400% D2 = 30 metros AB 397952 51960 13,057% 3151 0,792% 250 29 11,600% 99 39,600% BA 397096 101360 25,525% 3627 0,913% 250 75 30,000% 120 48,000%

Tabla 5.5. Tasa de prdida y error segn el largo del cable utilizado para la configuracin propuesta en la figura 5.16.

172

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica De la tabla anterior, se puede ver un similar comportamiento al observado con la configuracin anterior, en donde el comportamiento de los modems va empeorando a medida que se aumenta la longitud del cable, con un pico en 20 metros. Desde el punto de vista del sentido de la transmisin de las tramas, existen diferencias atribuibles a que los modems no son idnticos, y dichas diferencias aumentan a medida que se extiende la longitud del cable. En la tabla 5.6, se muestra el comportamiento promedio para cada una de las longitudes de prueba.
D2 = 1,5 metros D2 = 10 metros D2 = 20 metros D2 = 30 metros % Bits perdidos % Bits errneos % Tramas perdidas % Tramas errneas 9,618% 1,190% 9,400% 28,400% 13,892% 0,585% 13,400% 25,000% 30,266% 1,351% 32,000% 23,800% 19,291% 0,853% 20,800% 43,800%

Tabla 5.6. Tasa promedio de prdida y error segn el largo del cable utilizado para la configuracin propuesta en la figura 5.16.

El comportamiento promedio marca de igual modo que en la tabla 5.5 que el desempeo de los modems empeora con el aumento de la longitud del cable registrando un pico en 20 metros. A continuacin se evala el comportamiento segn el tipo de cable, fijando una longitud D2 en 5 metros. Para la prueba se utiliza cable comn y cable coaxil, para analizar la influencia del ruido inducido en la lnea de potencia.
Cable comn AB Bits enviados Bits perdidos % Bits perdidos Bits errneos % Bits errneos Tramas enviados Tramas perdidas % Tramas perdidas Tramas errneas % Tramas errneas 370368 53856 14,541% 1326 0,358% 250 40 16,000% 65 26,000% BA 407448 69592 17,080% 1405 0,345% 250 42 16,800% 56 22,400% Cable coaxil AB 402912 43848 10,883% 4241 1,503% 250 30 12,000% 71 28,400% BA 397384 37704 9,488% 1546 0,389% 250 24 9,600% 76 30,400%

Tabla 5.7. Tasa de prdida y error segn el tipo de cable utilizado para la configuracin propuesta en la figura 5.16.

FernandoArielBeunza79156

173

Tesis de Grado en Ingeniera Informtica En la tabla 5.7 se puede observar que el ruido inducido en la lnea es un factor importante ya que el desempeo de los modems mejora notablemente cuando el tramo de cable utilizado es coaxil. Tambin se pueden ver diferencias segn el sentido de la transmisin, que no son demasiadas debido a la corta longitud del cable utilizado. De similar forma que se realiz en las anteriores pruebas, se obtiene el comportamiento promedio, como se puede observar en la tabla 5.8.
Cable comn Cable coaxil % Bits perdidos % Bits errneos % Tramas perdidas % Tramas errneas 15,811% 0,352% 16,400% 24,200% 10,186% 0,721% 10,800% 29,400%

Tabla 5.8. Tasa promedio de prdida y error segn el tipo de cable utilizado para la configuracin propuesta en la figura 5.16.

Aqu, de forma mucho ms clara, puede observarse la mejora que existe al utilizar cable coaxil, destacando tambin como factor importante el ruido inducido en la lnea de potencia. Luego de realizadas todas las pruebas para las dos configuraciones propuestas, se pueden comparar los resultados obtenidos y determinar el comportamiento general de los modems evaluados. Para determinar el comportamiento se tiene en cuenta el porcentaje de bits perdidos (por prdida de tramas), de bits errneos, de tramas perdidas y de tramas errneas (que deben ser descartas por presentar algn bit errado). En las figuras 5.17 y 5.18, se muestran las tasas promedio de perdida de bits y de bits errneos en funcin de la longitud de cable utilizado.
35,000% 30,000% 25,000%

1,600% 1,400% 1,200%

Bits perdidos

Bits errneos
0 5 10 15 20 25 30 35

20,000% 15,000% 10,000% 5,000% 0,000%

1,000% 0,800% 0,600% 0,400% 0,200% 0,000% 0 5 10 15 20 25 30 35

Metros
AB BA

Metros
AB BA

Figura 5.17. Tasa promedio de bits perdidos segn Figura 5.18. Tasa promedio de bits errneos segn longitud del cable y disposicin de los modems longitud del cable y disposicin de los modems PLC. PLC.

Se puede observar en la figura 5.17 que la tasa de prdida de bits se incrementa con la longitud de cable con la particularidad de haber un pico en 20 metros. En la figura 5.18 se puede ver un tambin un pico en 1,5 metros, debido a que el ruido inducido no provoca demasiada prdida de tramas (como se observa en la figura 5.17), pero si altera el valor de los bits recibidos, lo que se traduce en el aumento de la tasa de bits errneos. Luego la curva del grfico de la figura 5.18 coincide con la tendencia mostrada en el grfico de la figura 5.17.

174

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica A continuacin se realiza el mismo anlisis, pero esta vez se toman en cuenta el porcentaje de tramas perdidas y errneas. A diferencia de los bits, en el caso de las tramas slo basta un bit errneo para descartar una trama completa (lo que hace la capa de enlace). Entonces los grficos de las figuras 5.19 y 5.20, reflejan que tan buenos son los modems transmitiendo informacin, sin tener en cuenta ningn mtodo que puede mejorar el desempeo de los mismos (como por ejemplo la fragmentacin de la informacin enviada, etc.).

35,000% 30,000%

50,000% 45,000% 40,000%

Tramas errneas
0 5 10 15 20 25 30 35

Tramas perdidas

25,000% 20,000% 15,000% 10,000% 5,000% 0,000%

35,000% 30,000% 25,000% 20,000% 15,000% 10,000% 5,000% 0,000% 0 5 10 15 20 25 30 35

Metros
AB BA

Metros
AB BA

Figura 5.19. Tasa promedio de tramas perdidas segn longitud del cable y disposicin de los modems PLC.

Figura 5.20. Tasa promedio de tramas errneas segn longitud del cable y disposicin de los modems PLC.

El grfico de la figura 5.19 es similar al de la figura 5.17 que trata sobre la tasa de bits perdidos. sto se debe a que cuando se pierde una trama, se pierden todos los bits de ella, por lo cual es de esperar un comportamiento similar reflejado en los grficos. En cambio, en el grfico de la figura 5.20, se puede observar que la tasa de prdida de tramas se mantiene por debajo del 35% hasta los 20 metros de longitud del cable y luego aumenta. ste comportamiento se debe a varios motivos: primero, con longitudes bajas (menos de 10 metros), el comportamiento es relativamente bueno; segundo, superando los 10 metros hasta los 20 metros, es donde hay mucha prdida de tramas por lo cual no se puede determinar si presentaban algn error (la trama perdida no se cuenta como errnea); y tercero, con ms de 20 metros es de esperar la prdida de tramas por la longitud por ruido inducido en la lnea de potencia que corrompe los bits de la tramas. Si se sumaran las tasas de tramas prdidas con las errneas, que corresponde al ambiente sobre el cual trabaja la capa de enlace (esta capa no tiene en cuenta si la trama se perdi o es errnea, en ambos casos pide retransmisin de la misma), en el mejor escenario, la tasa de prdida es superior al 30%. Una vez comparados los resultados obtenidos en funcin de la longitud del cable, se puede realizar el mismo anlisis comparativo modificando el tipo de cable utilizado. En este caso, se toman los mismos parmetros utilizados en la comparacin anterior (porcentaje de bits perdidos, de bits errneos, de tramas perdidas y tramas errneas). En las figuras 5.21 y 5.22, se muestran las tasas promedio de perdida de bits y de bits errneos en funcin del tipo de cable utilizado.

FernandoArielBeunza79156

175

Tesis de Grado en Ingeniera Informtica

25,000% 20,000%

0,800% 0,700% 0,600%

Bits errneos

Bits perdidos

15,000% 10,000% 5,000% 0,000% cable comn cable coaxil

0,500% 0,400% 0,300% 0,200% 0,100% 0,000% cable comn cable coaxil

Tipo de cable
AB BA

Tipo de cable
AB BA

Figura 5.21. Tasa promedio de bits perdidos segn tipo de cable y disposicin de los modems PLC.

Figura 5.22. Tasa promedio de bits errneos segn tipo de cable y disposicin de los modems PLC.

Observando los grficos anteriores se puede concluir que las diferencias entre los resultados obtenidos en las dos configuraciones de prueba utilizadas son mayores cuando se utiliza cable comn, dado que las pruebas son ms propensas a ser influidas por el ruido inducido en el cable utilizado. En el caso particular de la tasa de bits perdidos, se puede decir que el cable coaxil disminuye la prdida de bits; pero si se observa la tasa de bits errados, la cantidad de bits errneos es mayor comparada a la obtenida con cable comn. sto se debe a que los bits perdidos no son considerados como errneos, y que al haber menos prdida aumenta la probabilidad de error. Se puede concluir que el ruido inducido sobre la lnea de potencia afecta ms al proceso de deteccin de la trama, que a la informacin contenida en ella. A continuacin se realiza un anlisis similar al anterior, pero trabajando con tramas y no con bits. Los resultados analizados se puede observar en las figuras 5.23 y 5.24.

20,000% 18,000% 16,000% 14,000% 12,000% 10,000% 8,000% 6,000% 4,000% 2,000% 0,000% cable comn cable coaxil

35,000% 30,000%

Tramas errneas

Tramas perdidas

25,000% 20,000% 15,000% 10,000% 5,000% 0,000% cable comn cable coaxil

Tipo de cable
AB BA

Tipo de cable
AB BA

Figura 5.23. Tasa promedio de tramas perdidas segn tipo de cable y disposicin de los modems PLC.

Figura 5.24. Tasa promedio de tramas errneas segn tipo de cable y disposicin de los modems PLC.

176

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica Lo observado en los anteriores grficos reafirma la conclusin enunciada anteriormente. Aqu se ve con ms claridad que el ruido inducido en el cableado afecta ms a la deteccin de tramas que a la deteccin de la informacin contenida en ellas. En la figura 5.23 se puede ver la mejora que presenta el cable coaxil frente al cable comn, pero no se aprecia mejora en la figura 5.24, en donde el descarte de tramas por presentar bits errneos no mejora con la calidad del cable. Para finalizar con el anlisis comparativo se puede obtener el comportamiento promedio entre las dos configuraciones de prueba utilizadas y tener una idea general de desempeo de los modems. En la tabla 5.9 se muestran los porcentajes promedio de bits perdidos y errneos, y de tramas perdidas y errneas.
1,5 metros 10 metros 20 metros 30 metros % Bits perdidos % Bits errneos % Tramas perdidas % Tramas errneas 9,545% 0,958% 9,500% 30,200% 12,295% 0,510% 12,300% 24,900% 29,516% 1,325% 30,600% 24,200% 19,077% 0,922% 20,700% 43,100%

Tabla 5.9. Tasa promedio de prdida y error segn el largo del cable.

En general se puede decir que ms all de donde se ubiquen los modems el comportamiento empeora a medida que la longitud del cable entre ellos aumenta, existiendo un pico en el caso de los 20 metros. Los mismos valores pueden verse de otra forma por medio de las figuras 5.25, 5.26, 5.27 y 5.28.

35,000% 30,000% 25,000% 20,000% 15,000% 10,000% 5,000% 0,000% 0 5 10 15 20 25 30 35

1,400% 1,200% 1,000% 0,800% 0,600% 0,400% 0,200% 0,000% 0 5 10 15 20 25 30 35

Metros

Bits errneos

Bits perdidos

Metros

Figura 5.25. Tasa promedio de bits perdidos segn longitud del cable.

Figura 5.26. Tasa promedio de bits errneos segn longitud del cable.

FernandoArielBeunza79156

177

Tesis de Grado en Ingeniera Informtica

35,000% 30,000%

50,000% 45,000%

Tramas perdidas

25,000% 20,000% 15,000% 10,000% 5,000% 0,000% 0 5 10 15 20 25 30 35

Tramas erroneas

40,000% 35,000% 30,000% 25,000% 20,000% 15,000% 10,000% 5,000% 0,000% 0 5 10 15 20 25 30 35

Metros

Metros

Figura 5.27. Tasa promedio de tramas perdidas segn longitud del cable.

Figura 5.28. Tasa promedio de tramas errneas segn longitud del cable.

Como en los anlisis comparativos anteriores su pudo observar que las tasas promedio eran similares independientemente de la configuracin de prueba utilizada, los grficos que se pueden observar aqu reflejan la misma idea, en donde el desempeo desmejora con el aumento de la longitud de cable, con un pico de peor desempeo en 20 metros, y se tienen en cuenta las tramas perdidas y las errneas, se observa que la prdida de tramas por alguno de los dos motivos es superior al 40%.
Cable comn Cable coaxil % Bits perdidos % Bits errneos % Tramas perdidas % Tramas errneas 17,464% 0,442% 17,500% 24,200% 10,594% 0,727% 10,800% 28,000%

Tabla 5.10. Tasa promedio de prdida y error segn el tipo de cable. Con referencia al tipo de cable utilizado, la tasa de perdidas mejora con la calidad del cable, pero empeora la tasa de error debido a que al ser recibidos ms bits aumenta las probabilidades de ocurrencia de error.

5.1.4. Comparacin con DC-BUS


El diseo de DC-BUS provee una serie de funcionalidades de comunicaciones que corresponden a las capas fsica y de enlace del modelo OSI. DC-BUS est orientado a ofrecer un puente entre redes CAN y el medio fsico de comunicacin provisto por las lneas de potencia. De sta forma dispositivos existentes compatibles con CAN pueden comunicarse por medio de la lnea de alimentacin de un automvil por medio de DC-BUS. En cambio, la solucin propuesta en ste trabajo va ms all de implementar una interfaz fsica, sino que aborda toda la problemtica de las comunicaciones, implementando las siete capas del modelo OSI.

178

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica Tanto en DC-BUS como en la solucin propuesta, el medio fsico utilizado como canal de comunicacin son las lneas de potencia. Las diferencias se encuentran tcnicas de codificacin de los bits de datos. DC-BUS codifica los bits empleando dos portadoras, para brindar robustez en las comunicaciones, sin demasiadas complejidad de implementacin. La solucin propuesta emplea otra tcnica que permite, de forma no mucho ms costosa, utilizar 19 portadoras moduladas en DBPSK, lo que otorga mayor robustez que la ofrecida por DC-BUS. La desventaja que presenta ste ltimo mtodo frente al propuesto por DC-BUS es que ocupa mayor ancho de banda, que no permite ofrecer diversos tipos de comunicaciones como los ofrece DC-BUS. La topologa de red empleada por DC-BUS y la solucin propuesta, son idnticas ya que ambas alternativas trabajan sobre la red de alimentacin presente en un automvil. El mtodo de control de acceso al medio utilizado por DC-BUS se encuentra preparado para ser compatible con CAN. Se trata de un protocolo de la familia CSMA, que permite la resolucin de colisiones por medio de un mecanismo especialmente diseado para funcionar con las caractersticas de DC-BUS (no tiene la capacidad de deteccin de colisiones). La solucin propuesta en el presente trabajo, trabaja con una versin del protocolo CSMA/CA mejorado, que se basa en evitar las colisiones, ya que tambin existe el problema de no poder detectar colisiones. ste problema se encuentra en las dos alternativas debido a que ambos diseos no son capaces de transmitir y escuchar en forma simultnea, por razones de complejidad de implementacin. DC-BUS tiene la capacidad de brindar tres tipos de comunicaciones orientadas a tres tipos de aplicaciones. Brinda soporte para comunicaciones de baja velocidad utilizadas por aplicaciones de mecatrnica y uso general, comunicaciones de velocidad media requeridas por aplicaciones de telemtica, y comunicaciones de alta velocidad destinadas a aplicaciones de multimedia. sto se debe a lo explicado anteriormente sobre el modo de emplear el medio fsico, la simpleza en la forma de codificar la informacin y el ancho de banda utilizado, permiten implementar varios canales de comunicacin para diferentes tipos de comunicaciones. En cambio la solucin propuesta, por cuestiones de complejidad y ancho de banda utilizado, solamente puede brindar soporte a un solo tipo de comunicaciones que puede ser utilizado por aplicaciones generales o telemtica (velocidad de transferencia media a baja).

5.1.5. Comparacin con los trabajos sobre PLC en la industria automotriz


Los trabajos realizados por la Facultad de Ingeniera Elctrica de la Universidad Tcnica Checa de Praga no implementan un sistema de comunicacin comercial, sino que centran su esfuerzo en realizar un estudio sobre las lneas de potencia como un medio para transporte de datos, y propone un prototipo. sto si se tuviera que comparar frente al modelo de capas de OSI, se podra decir que los trabajos anteriores alcanzan solamente a la capa fsica. La propuesta del presente trabajo es ms evolucionada ya que toma como punto de partida el desarrollo de los anteriores trabajos y desarrolla las siete capas del modelo OSI, creando un prototipo ms funcional. En cuanto a lo referente al medio fsico, la topologa de red utilizada y capacidades, ambas propuestas son similares, ya que el presente trabajo ha sido inspirado por los trabajos anteriores. Existen algunas diferencias como el rango de frecuencias utilizado; la propuesta de la Facultad de Ingeniera Elctrica utiliza el rango comprendido entre 4 y 16 MHz, mientras que la solucin de ste trabajo trabaja en el rango comprendido aproximadamente entre 12 y 16 MHz. Otra diferencia se relaciona con la implementacin de los prototipos, la propuesta de los trabajos de la Facultad de Ingeniera Elctrica utiliza componentes de tecnologa superior a la empleada en la propuesta del presente trabajo. A pesar de sto ltimo, las prestaciones son similares; por ejemplo, la propuesta de FernandoArielBeunza79156 179

Tesis de Grado en Ingeniera Informtica la Facultad de Ingeniera Elctrica sintetiza directamente la seal smbolo con portadoras dentro del rango entre los 4 a 16 MHz, mientras que las solucin de ste trabajo sintetiza la seal smbolo en baja frecuencia (por debajo de los 3 MHz), y luego traslada la seal sintetizada por medio de un convertidor de frecuencias al rango comprendido entre 12 y 16 MHz (aproximadamente).

5.2. Comparacin con redes existentes para automviles


Luego de comparar la solucin propuesta por ste trabajo frente a las propuestas ofrecidas por las alternativas referentes a comunicaciones PLC para automviles, se realizan comparaciones frente a las redes de datos utilizadas en automviles en la actualidad. Para dichas comparaciones toman como referentes a las redes de datos para automviles analizadas en el captulo 2.

5.2.1. Comparacin con CAN


El modelo de capas propuesto por CAN se compone de la capa fsica y la capa de enlace, lo que le permite resolver los problemas bsicos de la comunicacin entre los dispositivos presentes en un automvil. La solucin propuesta por ste trabajo, adems de implementar las capas fsica y de enlace, implementa las restantes, siguiendo el modelo de capas propuesto por OSI. sto permite la implementacin de redes lgicas, transporte confiable de datos por medio de las anteriores, manejo de sesiones, estructurado de los datos transportados, e implementacin de una interfaz de aplicacin; lo que permite facilitar la implementacin de los dispositivos clientes. En cambio, cuando se trabaja con redes CAN, la implementacin de las funciones mencionadas anteriormente es responsabilidad del dispositivo que hace uso de CAN, lo que hace su implementacin ms compleja, o bien algunas de las funcionalidades no son implementadas. La capa fsica de CAN no especifica un medio fsico particular, lo que permite a stas redes poder expandir sus capacidades segn los avances tecnolgicos, sin realizar cambios de implementacin. La propuesta de ste trabajo, a diferencia de CAN, se encuentra estrechamente relacionada al medio fsico utilizado (lneas de potencia), ya que la capa fsica se encuentra diseada especficamente para resolver todos los problemas relacionados con el medio fsico utilizado. La consecuencia de sto es que si se desea trasladar la solucin propuesta a una nueva tecnologa que haga uso de otro medio fsico, o haga uso del mismo medio fsico pero de forma ms eficiente, se debe modificar la implementacin de la capa fsica. La topologa empleada por CAN es tipo lineal, un cableado que recorre el automvil interconectando cada uno de los dispositivos presentes en ste, con el inconveniente de que un dao en el cableado fragmente la red, impidiendo la comunicacin entre dispositivos encontrados en fragmentos distintos. La ventaja de la utilizacin de las lneas de potencia, es que la topologa de la red de alimentacin del automvil es hbrida, permitiendo la combinacin de topologas tipo estrella y tipo lineal, dando libertad de configuracin de la red para evitar o minimizar las posibilidades de que se fragmente la red por rotura de un tramo del cableado. El mtodo de acceso al medio utilizado por CAN permite un esquema multimaestro, en donde todos los dispositivos tiene la capacidad de enviar mensajes a otros. sto ltimo abre la posibilidad a la ocurrencia de colisiones que son resueltas por el protocolo CSMA/CR, en base a la prioridad de los mensajes, de forma determinstica. La solucin propuesta por sus caractersticas no es capaz de implementar un protocolo como el utilizado por CAN, pero implementa una versin 180 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica similar derivada del CSMA/CA, diseada para evitar las colisiones de mensajes, con el agregado de un esquema de prioridades. El protocolo no resulta ser determinstico, pero el esquema de prioridades introduce mejoras respecto a ste tema, comparado con la versin original CSMA/CA. La independencia de CAN sobre el medio fsico, permite la implementacin de redes con diversas capacidades. Pueden configurarse redes extensas para interconectar dispositivos que requieran comunicaciones de baja velocidad de transferencia, o bien redes de longitud limitada pero que permitan altas velocidades de transferencia de datos para aplicaciones crticas. Las tramas utilizadas por CAN para el transporte de datos presentan una capacidad limitada de 8 bytes, suficiente para las aplicaciones a las que se orienta este tipo de red. La propuesta de ste trabajo, solamente brinda soporte de comunicaciones a aplicaciones de uso general y de telemtica (velocidades de transferencia baja y media), y para expandir las capacidades se requiere de modificaciones a la implementacin de la capa fsica. Como ventaja sobre CAN, la solucin propuesta emplea tramas que pueden contener hasta 1024 bytes, ya que se encuentran orientadas a aplicaciones generales.

5.2.2. Comparacin con J1850


El estndar J1850 implementa las capas fsica y de enlace como CAN, con el agregado de una capa de aplicacin, lo que solamente le permite brindar los servicios bsicos de comunicacin entre los dispositivos presentes en un automvil, y diagnstico de los mismos. Las observaciones realizadas en la comparacin con respecto a la solucin propuesta por ste trabajo, son similares a las realizadas a CAN, con la diferencia que en ste caso se incorpora una capa de aplicacin. La capa fsica de J1850 define dos alternativas de cableado elctrico, una emplea un slo cable (J1850 VPW), y la otra dos cables (J1850 PWM). Para el caso de la propuesta del presente trabajo solamente se dispone de una sola variante. En ambas soluciones se puede apreciar la dependencia del diseo de la capa fsica con respecto al medio utilizado, lo que hace que un cambio tecnolgico sobre el medio fsico provoque un cambio en la implementacin de la capa fsica. La topologa empleada por J1850 es del tipo lineal, como en el caso de CAN. sta configuracin presenta las mismas desventajas con respecto a la propuesta de ste trabajo sealadas anteriormente, cuando se realiz la comparacin con CAN. El mtodo de acceso al medio utilizado por J1850 implementa un esquema multimaestro, con alguna similitud con el que emplea CAN, en donde todos los dispositivos tiene la capacidad de enviar mensajes. La consecuencia natural de sto ltimo es la posibilidad a la ocurrencia de colisiones que son resueltas por el protocolo CSMA/CR, en base a la prioridad de los mensajes, de forma determinstica. La solucin propuesta por sus caractersticas no es capaz de implementar un protocolo como el utilizado por J1850, pero implementa una versin mejorada del protocolo CSMA/CA. Las redes J1850 se encuentras preparadas para dar soporte a aplicaciones generales que requieren de velocidades de transferencia bajas. Aunque J1850 ofrece dos alternativas, ambas se encuentran por debajo de los 100 kbps, lo que ofrece una capacidad bastante limitada. Las tramas utilizadas por J1850 para el transporte de datos pueden tener hasta 12 bytes (incluyendo informacin de control), suficiente para las aplicaciones a las que se orienta este tipo de red. La solucin propuesta por el presente trabajo, brinda soporte de comunicaciones a aplicaciones de uso general y de telemtica (velocidades de transferencia baja y media), por lo cual trabaja con tramas que pueden contener hasta 1024 bytes, ya que se encuentran orientadas a aplicaciones generales.

FernandoArielBeunza79156

181

Tesis de Grado en Ingeniera Informtica

5.2.3. Comparacin con OSEK/VDX


La propuesta OSEK/VDX es independiente de los sistemas de comunicaciones utilizados por los dispositivos. Fue diseado con el objetivo de proveer una plataforma comn de desarrollo de software para los dispositivos, para independizar los aspectos del hardware de comunicacin de las aplicaciones de los dispositivos. Siguiendo el modelo de capas propuesto por OSI, puede decirse que las capas fsica y de enlace corresponden al sistema de comunicacin sobre el cual trabaja OSEK/VDX, mientras que OSEK/VDX implementa la capa de red y la interfaz de aplicacin (capa de aplicacin). ste estndar pretende implementar las capas no implementadas por CAN y J1850, aunque no implementa las siete del modelo OSI. La solucin de ste trabajo adems de incluir las capas fsica y de enlace, tambin implementa las de transporte, sesin y presentacin; lo que la hace ms compleja que OSEK/VDX. Con respecto al medio fsico, topologa de red y capacidades; ests dependen del estndar de comunicacin sobre el cual se implemente OSEK/VDX, lo que no ocurre con la solucin propuesta por el presente trabajo (porque define la capa fsica y de enlace).

5.2.4. Comparacin con LIN


El objetivo de LIN es proveer un sistema de comunicacin entre dispositivos a bajo costo, por lo cual se hace necesario reducir la complejidad de la implementacin de los dispositivos. Por sta razn LIN solamente implementa dos de las siete capas propuestas por el modelo OSI, que son la capa fsica y la capa de enlace. La solucin propuesta por ste trabajo se encuentra orientada a ofrecer una alternativa con mayor funcionalidad que la provistas por otro tipo de redes como CAN o J1850, ms complejas que LIN, por eso implementa las siete capas del modelo OSI. Se debe recordar que LIN trabaja junto a CAN y J1850, de forma tal que LIN permite interconectar dispositivos cercanos entre s de baja complejidad, y CAN y J1850 se emplean como red de interconexin entre las diferentes redes LIN que pueden existir en un automvil. En stos momentos la complejidad de las comunicaciones PLC hace dificultoso trasladarlas a dispositivos de baja complejidad. La capa fsica implementada por LIN trabaja utilizando como medio fsico un slo cable que permite interconectar dispositivos de forma simple y econmica. La solucin propuesta por ste trabajo, aprovecha las lneas de alimentacin del automvil, lo que hace a ste medio fsico tambin una alternativa simple y econmica (ya que se aprovecha algo existente). La topologa de red adoptada por LIN es del tipo lineal, como CAN y J1850, con los mismos inconvenientes frente a la solucin propuesta que propone una topologa hbrida. Las redes LIN trabajan bajo un esquema de maestro/esclavo, a diferencia de la solucin propuesto que presenta un esquema multimaestro. De esta forma, LIN controla el acceso al medio de forma simple y eficaz, eliminando la posibilidad de colisiones de mensajes, como ocurre con la solucin propuesta por el presente trabajo. La desventaja del esquema utilizado por LIN, es que el dispositivo maestro es un dispositivo nico, que en caso de falla, deja de funcionar la red completa, lo que no sucede con un esquema multimaestro. LIN se encuentra destinada a dar soporte de comunicaciones a aplicaciones generales que requieren de bajas velocidades de transferencia, ofreciendo diversas opciones de velocidad. En cambio la solucin propuesta en ste trabajo ofrece una nica opcin de velocidad de rango medio porque est orientado a un ambiente de trabajo diferente.

182

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

5.2.5. Comparacin con D2B


El estndar de comunicacin D2B se encuentra diseado para ofrecer servicios de transmisin de datos a alta velocidad para aplicaciones de multimedia en automviles. ste estndar, al igual que otros, implementa las capas fsica y de enlace propuestas por el modelo OSI; dejando sin resolver algunas cuestiones del proceso de comunicacin que deben ser resueltas por los dispositivos que hacen uso de D2B, a diferencia de la propuesta del presente trabajo que opta por implementar todas las capas del modelo OSI para no incrementar la implementacin de los dispositivos clientes. La caracterstica que diferencia D2B del resto de las redes es que introduce como medio fsico para transmisin de datos la fibra ptica. La capa fsica implementa una red de fibra ptica dedicada al transporte de datos y una red cableada para seales de control. La utilizacin de fibra ptica permite trabajar con altas velocidades de transferencia requeridas por las aplicaciones multimedia gracias a su inmunidad al ruido electromagntico, a diferencia de la solucin propuesta por el presente trabajo que encuentra limitada su capacidad, y destina muchos recursos, en brindar un servicio de comunicacin por medio de la red de alimentacin de un automvil, caracterizada por la gran presencia de ruido electromagntico. La capa fsica, tanto en D2B como en la solucin propuesta son dependientes del medio fsico, por lo cual un cambio en ste ltimo implica una modificacin en la implementacin de la capa fsica. La topologa de red que presenta D2B es muy particular, ya que dispone de un canal ptico y un canal elctrico, cada uno con una topologa distinta. La red de fibra ptica presenta una topologa tipo anillo, mientras que la red elctrica adopta una topologa tipo estrella. sta configuracin de red no ofrece el grado de libertad que presenta la red de alimentacin de un automvil, medio utilizado para la propuesta de ste trabajo. La topologa tipo anillo de D2B requiere de un dispositivo con funciones de maestro, lo cual hace de sto su punto de debilidad ante fallas; algo que no ocurre en un esquema multimaestro como el implementado en la solucin propuesta por ste trabajo. El control de acceso al medio provisto por D2B consiste en el mtodo de paso de testigo, el cual asegura un tiempo determinstico y un canal libre de colisiones. En cambio, la propuesta del presente trabajo emplea un protocolo CSMA/CA mejorado que no asegura tiempo determinstico ni un canal libre de colisiones (solamente las evita). Por las caractersticas de D2B, resulta relativamente sencillo implementar un esquema de paso de testigo ya que aprovecha la existencia de un dispositivo maestro que ejerce el rol de supervisor de red, lo que no ocurre en un esquema multimaestro. El inconveniente del mtodo de paso de testigo es que ante la falla del dispositivo maestro, el resto de los dispositivos no pueden comunicarse entre s, lo que no sucede en un esquema multimaestro. Las capacidad de transferencia de datos que presenta D2B es muy superior a la propuesta de ste trabajo, ya que la fibra ptica permite comunicaciones de alta velocidad, lo que no ocurre con las lneas de potencia. A pesar de sto, la fibra ptica es un medio fsico bastante delicado por lo cual las redes D2B estn pensadas para interconectar dispositivos presentes dentro del habitculo de pasajeros del automvil, a diferencia de las lneas de potencia que se encuentran presentes en todas las partes del automvil. Por sta razn, D2B resulta se adecuada para aplicaciones multimedia ya que stas residen dentro del habitculo de pasajeros del automvil; a diferencia de otro tipo de aplicaciones que no necesitan altas velocidades de transferencia, pero se encuentran en todas partes del automvil, y en ste ltimo caso resulta ms adecuado lo que ofrece la propuesta del presente trabajo.

FernandoArielBeunza79156

183

Tesis de Grado en Ingeniera Informtica

5.2.6. Comparacin con MOST


El estndar MOST es una mejora con respecto a D2B, estudiado anteriormente; aunque conserva muchas similitudes. MOST se encuentra diseado para ofrecer comunicaciones de alta velocidad para aplicaciones de multimedia en automviles. ste estndar se encuentra constituido por tres capas: capa fsica, capa de red y capa de aplicacin; siendo la capa de red equivalente a las capas de enlace, red y transporte del modelo OSI. A pesar de ser un estndar que implementa ms funcionalidades no implementa la capa de presentacin, a diferencia de la solucin propuesta en ste trabajo que implementa las siete capas del modelo OSI. La capa fsica de MOST est pensada para funcionar utilizando como medio fsico tanto cableado elctrico como ptico (mejora respecto de D2B). La fibra ptica utilizada es de mejor calidad a la empleada en D2B, lo que permite mayores longitudes y capacidades de transferencia. Al igual que D2B, MOST tambin trabaja con una red de cableado ptico y cableado elctrico. La propuesta de ste trabajo implementa una capa fsica dependiente del medio fsico utilizado (lneas de potencia), a diferencia de MOST. Con respecto a las ventajas de la fibra ptica sobre las lneas de potencia, son las mismas que las detalladas en la comparacin con D2B. La topologa de red que presenta MOST es muy similar a la que posee D2B. La red de fibra ptica adopta una topologa tipo anillo, mientras que la red de cableado elctrico presenta una topologa tipo estrella. Al igual que en D2B, en MOST existe un dispositivo maestro, con todas las ventajas y desventajas que tiene ste ltimo. Con respecto a la propuesta del presente trabajo, las observaciones son similares a las realizadas con referencia a D2B, la topologa de la red de alimentacin y el esquema multimaestro, presenta menos lmites que la propuesta de D2B y MOST. El control de acceso al medio implementado por MOST tambin consiste en el mtodo de paso de testigo, como el empleado por D2B. El tiempo determinsitco y comunicaciones libre de colisiones son sus puntos a favor frente al protocolo implementado por la propuesta de ste trabajo, mientras que el esquema maestro/esclavo es el punto en contra. La capacidad de transferencia de datos de MOST supera al mismo D2B gracias a la mejora en la calidad de la fibra ptica utilizada. A pesar de que la red puede ser ms extensa, por la calidad de la fibra ptica, no es adecuada para cualquier lugar dentro del automvil as que sigue reservada a uso dentro del habitculo de pasajeros del automvil para la interconexin de los distintos dispositivos multimedia que pueden existir. Adems de la velocidad, MOST supera a la propuesta de ste trabajo, en la cantidad de bytes que puede transportar una trama, ya que las tramas MOST pueden contener hasta 1524 bytes, mayor a los 1024 bytes ofrecidos por la solucin propuesta de ste trabajo. Tambin MOST ofrece diversas formas de transporte de datos que pueden ser: paquetes de datos de control, paquetes de datos comunes y flujos de datos; de sta forma se pueden transportar datos entre los distintos dispositivos, y flujos de datos correspondientes a audio y video. La propuesta de ste trabajo slo se limita a brindar un servicio de transporte de datos por medio de paquetes, ya que sta orientado a aplicaciones generales y no de multimedia.

5.2.7. Comparacin con FlexRay


Las redes FlexRay fueron pensadas para aplicaciones crticas que requieren comunicaciones de alta velocidad. La idea de ste estndar es presentar una evolucin a redes CAN de alta velocidad. FlexRay, como muchos otros estndares, implementan las dos primeras capas del modelo OSI, denominadas capa fsica y capa lgica (equivalentes a las capas fsica y de enlace), y de sta forma brinda los servicios bsicos de comunicacin entre dispositivos. La solucin propuesta por el

184

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica presente trabajo se orienta ms a ofrecer servicios de comunicacin ms avanzados sobre el alto desempeo que ofrece FlexRay. La capa fsica de FlexRay utiliza un medio fsico que permite a un bajo costo, comparado con soluciones que emplean fibra ptica, comunicaciones confiables de alta velocidad. El medio fsico empleado es cable par trenzado sin blindaje, ms inmune al ruido electromagntico que el cableado elctrico utilizado para alimentacin, utilizado por la propuesta de ste trabajo. sto determina las diferencias de capacidades que existen entre FlexRay y la solucin propuesta por ste trabajo. En ambos casos la capa fsica es dependiente del medio fsico, por lo cual una evolucin tecnolgica de ste ltimo debe ir acompaado de una evolucin de la implementacin de la capa fsica. Los dispositivos compatibles con FlexRay presenta una particularidad nica con respecto a los otros estndares analizados en ste trabajo, stos pueden conectarse a dos cableados diferentes. De sta manera FlexRay brinda dos canales de comunicacin que pueden ser utilizados en simultneo por los dispositivos, aumentando la velocidad y confiabilidad de las comunicaciones. sta caracterstica permite que las redes FlexRay puedan implementar diversas topologas, pueden configurarse redes con topologa lineal, estrella o combinacin de ambas, respetando algunas restricciones impuestas por el estndar. De sta forma FlexRay se asemeja a la solucin propuesta por el presente trabajo, en cuanto a los beneficios que presentan las topologas hbridas. En cuanto al control de acceso al medio, FlexRay implementa ciclos de tiempo de recurrente compuesto por un segmento esttico y uno dinmico. El segmento esttico se compone de ranuras de tiempo de longitud fija, cada una asignada un identificador de trama y a un determinado nodo, no existiendo posibilidad de colisiones. El segmento dinmico se compone de ranuras de longitud variable y su uso se determina en base a la prioridad de la trama a enviar, para resolver las colisiones. De sta forma FlexRay ofrece un control mixto de acceso al medio, uno libre de colisiones y otro con resolucin de colisiones en base a prioridad, en comparacin a la solucin propuesta por ste trabajo que slo ofrece un esquema CSMA/CA mejorado, que tambin se basa en la prioridad. En cuanto a las capacidades, FlexRay es notablemente superior a la propuesta de ste trabajo ya que puede alcanzar hasta 10 Mbps de velocidad de transferencia, frente a los aproximados 140 Kbps ofrecidos por la solucin propuesta. FlexRay est destinado a dispositivos de aplicaciones crticas que requieren de velocidades altas de transferencia para funcionar de forma adecuada, en cambio la propuesta del presente trabajo est orientado a aplicaciones generales y telemtica que trabajan con velocidades bajas a medias. Respecto al tamao de las tramas, FlexRay trabaja con tramas que pueden alcanzar hasta 262 bytes, mucho mejor que otro tipo de redes como CAN y J1850; aunque no supera a la capacidad de transporte ofrecida por la propuesta de este trabajo de 1024 bytes.

5.3. Caractersticas particulares de la solucin propuesta


Con anterioridad se han analizado los puntos en comn que presenta la solucin propuesta por el presente trabajo y otras alternativas aplicadas en automviles. Se determinaron las ventajas y desventajas de la solucin propuesta frente a las otras alternativas, pero quedaron pendientes de estudio ciertas particularidades que ofrece la solucin propuesta y no las alternativas. La primer particularidad, vista en el anlisis comparativo realizado con anterioridad, es que ninguna alternativa existente implementa de forma completa las siete capas propuestas por el modelos OSI. Generalmente implementan las capas fsicas y de enlace, y en algunos casos la capa FernandoArielBeunza79156 185

Tesis de Grado en Ingeniera Informtica de aplicacin. Algunas alternativas unifican funcionalidades especificadas en varias capas del modelo OSI en una capa de su propio modelo, y otras funcionalidades ni siquiera son implementadas, como por ejemplo las funcionalidades de la capa de presentacin. Los motivos son comprensibles ya que buscan reducir costos de implementacin de los dispositivos, dejando de lado funcionalidades. La solucin propuesta en ste trabajo, por su carcter de prototipo, no persigue fines de eficiencia, sino que propone una alternativa de la cual se puedan extraer ideas para futuros trabajos. Por sta razn, implementa las siete capas siguiendo al modelo OSI, para mostrar las ventajas de implementar todas las funcionalidades, que en el futuro, con el desarrollo de la tecnologa de microcontroladores, puede resultar econmico y factible la implementacin de dispositivos que contengan las siete capas. Igualmente la solucin propuesta intenta acercarse a la realidad y proponer una forma de implementacin que no demande tantos recursos a los dispositivos clientes, distribuyendo las siete capas entre el dispositivo cliente y el modem PLC. En el dispositivo cliente se implementan las capas de aplicacin y presentacin, porque se relacionan inevitablemente con la plataforma utilizada para la implementacin de ste dispositivo. En cambio las restantes capas pueden implementarse en un microcontrolador aparte. La forma de implementacin de la solucin propuesta descripta anteriormente abre una posibilidad que no ofrece ninguna alternativa estudiada. Al implementar cinco de las siete capas en un microcontrolador dedicado se dispone de un ncleo independiente del dispositivo cliente, que puede ser un dispositivo real que realice una tarea en concreto o puede ser un dispositivo virtual. En diseo de las capas no impide que puedan desarrollarse las capas de aplicacin y de presentacin dentro de una PC, y que una aplicacin dentro de sta simule el funcionamiento de un dispositivo cliente. sta caracterstica es muy importante ya que contribuye en el desarrollo de dispositivos clientes de forma econmica, ya que se pueden simular antes de implementarse. Dentro de una PC, para simular los dispositivos clientes deben crearse aplicaciones por medio de algn lenguaje de programacin que utiliza la interfaz provista por la capa de aplicacin. No siempre los desarrolladores de dispositivos clientes tienen conocimientos de programacin, por lo cual la solucin propuesta incluye una interfaz grfica que se encuentra por encima de la capa de aplicacin. La interfaz grfica consiste en un conjunto de bloques funcionales Simulink, que permite desarrollar realizando un modelo grfico que las funcionalidades que debe cumplir el dispositivo cliente en desarrollo a simular.

5.4. Desempeo de la solucin propuesta


Para evaluar como se desempea el sistema desarrollado en ste trabajo en forma conjunta se propone un esquema de prueba, cuyos detalles se especifican en el Apndice G (Implementacin de pruebas). La evaluacin consiste en observar el funcionamiento del sistema desde el nivel de capa de aplicacin. sto se realiza por medio de aplicaciones de prueba desarrolladas en diferentes entornos (C, C++ y Simulink), para tambin incluir en la evaluacin a las extensiones del sistema desarrolladas. La configuracin de la red implementada para la realizacin de las pruebas es similar a la utilizada para evaluar el funcionamiento del mdulo analgico y el mdulo de procesamiento de seales. Tambin se incluye un dispositivo cliente real conectado a uno de los modems PLC, de forma tal de implementar un esquema de comunicacin entre un dispositivo cliente real y un dispositivo cliente virtual, implementado por las aplicaciones de prueba anteriormente mencionadas ejecutndose en una PC conectada al otro modem. Para supervisar el funcionamiento de la red se emplean las herramientas de depuracin provistas por el sistema desarrollado, que ahorran la implementacin de un dispositivo de diagnstico (que requiere de un tercer modem PLC), o la

186

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica implementacin de una aplicacin de diagnstico que se ejecute en la misma PC donde se encuentra el dispositivo cliente virtual. El dispositivo cliente real consiste simplemente en un dispositivo que simula un sistema de iluminacin de un automvil, con distintos focos de iluminacin accionados por diferentes mensajes. El dispositivo cliente virtual es una aplicacin que simula un dispositivo que acciona los focos de iluminacin del dispositivo cliente real. De sta forma se puede evaluar como funciona el sistema en comparacin al modo utilizado tradicionalmente en un automvil para comandar las luces de iluminacin. Las aplicaciones de prueba y el modelo Simulink de prueba implementan una secuencia de encendido y apagado de los diferentes focos de iluminacin implementados en el dispositivo cliente real. De sta forma se puede comprobar, por simple observacin, que la velocidad de respuesta no es tan veloz como en un sistema de iluminacin tradicional. sto se debe a que el poder de computo de los microcontroladores utilizados en la implementacin de los modems PLC no es suficiente para dar una respuesta en tiempo real, como requiere el accionamiento de los focos de iluminacin. Sin embargo, la calidad de servicio brindada por el sistema desarrollado sera adecuada para aplicaciones que suministren informacin de baja velocidad de variacin (nivel de combustible, temperatura de motor, etc.) y otros dispositivos de uso general (control de la radio, etc.). Un resultado as era esperable, ya que la propuesta presentada en el presente trabajo es un prototipo orientado a implementar un sistema de comunicaciones para aplicaciones de uso general, colocando su nfasis en demostrar que se lo puede implementar sobre las lneas de alimentacin, y siguiendo el modelo de capas OSI. Demostrado sto ltimo queda abierta la posibilidad futura de continuar avanzando en trabajos futuros para mejorar el desempeo.

FernandoArielBeunza79156

187

Tesis de Grado en Ingeniera Informtica

188

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

6. Conclusiones
En ste ltimo captulo del presente trabajo se describen las conclusiones que se pueden extraer a partir del anlisis de los resultados obtenidos de la evaluacin de la solucin propuesta realizada en el captulo anterior. A partir de los logros obtenidos y de los aspectos mejorables de la propuesta presentada, se pueden definir futuras lneas de investigacin para trabajos futuros que quieran contribuir con el desarrollo de las comunicaciones PLC para automviles.

6.1. Anlisis de resultados


Una de las conclusiones a la que se puede arribar a partir del presente trabajo es que se ha demostrado el potencial de plantear un sistema para el ambiente automotriz que siga el modelo de siete capas de OSI. Como se analiz con anterioridad, cuando se habl del antecedente OSEK/VDX, se mencion que la idea ste antecedente era implementar una plataforma estndar para permitir la interoperabilidad de los distintos dispositivos presentes en un automvil, y de sta manera simplificar la implementacin de los dispositivos y bajar los costos de los mismos. Seguir las pautas del modelo OSI, en cualquier mbito de aplicacin, logra ese objetivo porque el modelo de capas persigue el fin de independizar los distintos elementos que conforman el proceso de comunicacin (hardware, medio fsico, protocolos de transporte de informacin, etc.). Las redes IP son un ejemplo de las ventajas ofrecidas por el modelo de capas, ya que ha permitido bajar los costos de las mismas y difundirlas a muchos mbitos de aplicacin. La misma idea se pretende aplicar al mbito de los automviles para bajar los costos de los mismos, en tiempos en donde cada vez se integran ms dispositivos electrnicos a los mismos. Los microcontroladores actuales son capaces de cubrir el costo de procesamiento demandado por las siete capas, aunque no en todas partes del mundo se tiene libre acceso a los mismos, por lo cual todava no resulta del todo conveniente la introduccin de sta tecnologa en automviles que pretendan ser vendidos en cualquier parte del mundo. Otra cuestin que se demuestra en ste trabajo, es el potencial que presentan las comunicaciones PLC. Siempre se ha estudiado el problema que presentan las redes cableadas en cuanto a costos de instalacin, y las ventajas de las redes inalmbricas sobre sta ltimo problema. Las redes PLC poseen cualidades comunes a los dos tipos de redes anteriores: las lneas elctricas llegan a todos los lugares donde existan dispositivos electrnicos (ahorro de instalacin de una red para datos), y stas son un medio guiado (sin los inconvenientes que presentan las redes inalmbricas). Igualmente, las lneas de potencia tienen en su contra, que no fueron diseadas para la transmisin de datos, lo que requiere de inteligencia adicional en los dispositivos de comunicacin para brindar un servicio de transporte de datos de forma confiable. El aprovechamiento de las lneas de potencia en infraestructura edilicia se ha demostrado que es factible segn los antecedentes en la materia estudiados en el presente trabajo, aunque existen estndares comerciales todava se contina trabajando en el tema, ya que todava existen discusiones sobre las interferencias que pueden causar las comunicaciones PLC en otros dispositivos que trabajan en los mismos rangos de frecuencia. En el ambiente de un automvil resulta cada vez ms necesario formas de interconexin de dispositivos electrnicos que economicen el uso de cableado, ya que cada vez se emplean ms dispositivos y los cableados dedicados resultan voluminosos y poco confiables susceptibles a interferencia por agrupar demasiados conductores en volmenes reducidos. Redes como CAN, J1850, LIN, D2B, MOST y FlexRay; proponen alternativas de interconexin que superan las dificultades del cableado dedicado, aunque el aumento de la cantidad de dispositivos ya vuelve complejos los cableados actuales de los FernandoArielBeunza79156 189

Tesis de Grado en Ingeniera Informtica automviles. Introducir la tecnologa PLC en los automviles resulta una idea adecuada ya que se reduce al mnimo el cableado, ya que siempre se va a requerir de alimentacin a los dispositivos por lo cual la red de alimentacin nunca se podr eliminar. Es un medio fsico con algunas dificultades adicionales con respecto a las lneas de potencia presentes en infraestructura edilicia, es un medio mucho ms ruidoso que dificulta las comunicaciones confiables; de hecho las redes utilizadas en la actualidad se caracterizan por su robustez ante interferencias, y hasta emplean fibra ptica para transmisiones de alta velocidad. Sin embargo, el poder de los microcontroladores en aumento permite la implementacin de tcnicas de modulacin y codificacin de la informacin que permiten comunicaciones de mejor calidad, a pesar del medio sobre el cual se llevan a cabo. El diseo del prototipo alcanza resultados satisfactorios comparado con el prototipo propuesto por los trabajos realizados por la Facultad de Ingeniera Elctrica de la Universidad Tcnica Checa de Praga. Aunque la tecnologa aplicada para la implementacin del prototipo propuesto por el presente trabajo es inferior a la utilizada en el prototipo propuesto en el antecedente mencionado anteriormente, cumple con los requerimientos bsicos necesarios para demostrar el funcionamiento correcto del conjunto que compone la propuesta planteada por ste trabajo. Gracias a sto se puede decir que en el futuro, se puede proponer un prototipo ms evolucionado tecnolgicamente, y se van obtener iguales o mejores resultados ya que muchos conceptos planteados en el presente trabajo continan siendo vlidos independientemente de la tecnologa de implementacin, porque el modelo de capas adoptado permite sto ltimo. Aunque el servicio de comunicacin que puede brindar el sistema propuesto en el presente trabajo no alcance la calidad de estndares comerciales, en cuanto a soluciones determinsticas como por ejemplo las ofrecidas por CAN y J1850, o altas velocidades de transferencia como D2B, MOST y FlexRay; se debe recordar que el desarrollo se trata de un prototipo que fundamentalmente pretende evaluar la viabilidad de la propuesta y servir para la construccin en un futuro de un sistema comercial que tome como antecedentes los conceptos probados en ste trabajo. La solucin propuesta tiene inconvenientes similares que el antecedente DC-BUS, a la hora de implementar un mecanismo de control de acceso al medio, porque a diferencia de muchas de las redes de datos de automviles que pueden escuchar el medio fsico y transmitir en simultneo, stas no lo pueden realizar por cuestiones de complejidad en la implementacin. Los mecanismos implementados en ambos casos fueron diseados especialmente, DC-BUS implementa un mecanismo propio, mientras que la solucin propuesta en ste trabajo adapta el protocolo CSMA/CA y lo combina con un esquema de prioridad para acercarlo a una solucin determinstica. De todos modos, el prototipo no fue pensado para aplicaciones crticas sino para aplicaciones generales y telemtica que requieren velocidades bajas y medias. El empleo de microcontroladores ms potentes en un futuro podra mejorar el sistema prototipo propuesto para brindar varios tipos de servicios de comunicaciones como ofrecen, por ejemplo MOST y FlexRay, paquetes de datos, flujos de datos de multimedia, etc. La implementacin de las siete capas por parte del solucin propuesta en ste trabajo permite la introduccin de funcionalidades no encontradas en las alternativas para automviles estudiadas. Una de ellas es el concepto de redes lgicas, por lo cual se independiza la red fsica asociada al cableado instalado, de como se organizan los distintos dispositivos conectados a la red anterior. ste concepto es tomado de las redes IP, donde el protocolo IP de la capa de red implementa un esquema de direccionamiento y de encaminado de paquetes independiente del soporte fsico utilizado para comunicaciones. De ste modo se da libertad de evolucin a las capas inferiores (capa fsica y de enlace), ms vinculadas al hardware y de ms rpida evolucin acompaando a las nuevas tecnolgicas. Otro aspecto que merece ser analizado es el transporte de datos, que aunque muchos de los antecedentes estudiados no implemente una capa de transporte especfica, resuelven de alguna forma la problemtica relacionada con ste tema. En general, el transporte de datos de forma confiable, viene garantizado por la capa de enlace, por ejemplo CAN y J1850 implementan un 190 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica mecanismo de multicast confiable, D2B y MOST trabajan con esquema de paso de testigo. sta manera de encarar el problema resulta las ms simple de implementar, a diferencia de redes IP que requieren de un protocolo de transporte de una cierta complejidad, aceptable en una computadora, pero que resulta inadecuada para la implementacin de dispositivos de un automvil. La solucin propuesta tambin toma la idea de sus antecedentes y fortalece las capacidades de la capa de enlace, lo que le permite implementar una capa de transporte ms simple que la del modelo TCP/IP. Los servicios brindados por sta capa de transporte son dos tipos de mensajera, una de mensajes secuenciados orientadas a transporte de datos de configuracin de dispositivo que no requieren urgencia pero si garanta de que lleguen a destino y en siguiendo un orden, y otro de mensajes no secuenciado orientado a rdenes que requieren que lleguen a destino lo ms rpido posible. Como ya se hizo mencin con anterioridad, la solucin propuesta no ofrece otros tipos de servicios de comunicacin orientados por ejemplo a multimedia, como si lo ofrece MOST, ya que se trata de un sistema prototipo cuyo objetivo no es proponer un sistema comercial, aunque el diseo no impide que en el futuro se puedan proponer nuevas ideas. El diseo del prototipo de modem PLC implementa las capas fsica, de enlace, red, transporte y sesin; no puede implementar las capas de presentacin y aplicacin porque dependen del dispositivo cliente. Si se quisiera implementar las siete capas de forma conjunta debe realizarse dentro del mismo microcontrolador del dispositivo cliente, por la dependencia mencionada anteriormente. Las capas de presentacin y aplicacin son dependientes del dispositivo cliente porque la primera est relacionada como se representan y estructuran los datos (dependiente de la plataforma), y la segunda es la interfaz con la cual se relaciona la aplicacin cliente con el sistema de comunicacin. Ninguno de los antecedentes analizados en ste trabajo implementa la capa de presentacin, salvo el modelo LonWorks que implementa las siete capas pero no se utiliza en automviles; trasladndose el problema al dispositivo cliente para que lo resuelva de alguna forma. En cambio la propuesta del presente trabajo, resuelve todos los problemas planteados por cada una de las siete capas, y disea el prototipo para que la solucin tenga la mejor relacin costo beneficio para el dispositivo cliente (agrega la implementacin de dos capas, pero el sistema ofrece los beneficios de las siete). Un beneficio adicional, a consecuencia de lo anterior, es que se puede implementar una versin de capa de presentacin y de aplicacin para PC. La propuesta del presente trabajo las implementa para brindar una herramienta de simulacin de dispositivos clientes, que resulta de gran utilidad para el diseo y posterior implementacin de los mismos, algo no ofrecido por ninguno de los antecedentes estudiados. Tambin permite la implementacin de un entorno grfico como Simulink para el modelado de dispositivos clientes virtuales, que libera a los desarrolladores de dichos dispositivos de tener conocimientos de programacin

6.2. Trabajos futuros


Los trabajos futuros para contribuir en ste arte deben estar orientados a tomar las ideas planteadas en el presente trabajo, mejorando los xitos logrados y avanzar sobre los aspectos mejorables, sealados con anterioridad. La solucin propuesta en el presente trabajo es un sistema prototipo con todas las limitaciones del mismo, no puede ser visto como un sistema comercial, por lo cual una de las lneas de investigacin puede derivar en optimizacin del sistema prototipo. Tambin se pueden seguir otras lneas de investigacin que incluyan partes y no la totalidad de la solucin propuesta, por ejemplo el modelo de siete capas es independiente de la tecnologa PLC y puede aplicarse a otras tecnologas de comunicacin presentes en un automvil. Incluso se puede pensar en adaptar la solucin propuestas a otras aplicaciones diferentes al automvil; por ejemplo

FernandoArielBeunza79156

191

Tesis de Grado en Ingeniera Informtica maquinaria agrcola, barcos, aviones, etc. La solucin propuesta podra adaptarse a todo mbito en donde exista el problema de reduccin de cableado como ocurre en los automviles. Uno de los aspectos mejorables a la solucin propuesta por el presente trabajo se encuentra relacionado con las tcnicas de modulacin y codificacin de la informacin. La implementacin propuesta resulta en una solucin bsica orientada a brindar servicios de comunicacin elementales. Conociendo las opciones que brindan algunos antecedentes estudiados, se puede tomar la idea planteada por DC-BUS de trabajar con varias bandas de frecuencia para proveer distintos tipos de canales de comunicacin para aplicaciones generales, telemtica y multimedia. Tambin se puede mejorar la velocidad de transferencia empleando otras tcnicas de modulacin y codificacin de la informacin que requieren necesariamente mayor capacidad de computo por parte del microcontrolador utilizado para implementar el modem PLC. Algo relacionado con el tema anterior, y tambin mejorable es el protocolo de control de acceso al medio. Si en el futuro se desea brindar soporte para comunicacin de diversos tipos de datos, como paquetes de datos, multimedia, etc., como por ejemplo brinda MOST, debe volverse a plantear el protocolo de acceso al medio; los paquetes de datos pueden contener informacin crtica o no (por lo cual las caractersticas del protocolo empleado pueden variar), y la informacin multimedia requiere la asignacin de un ancho de banda constante. Por un razn lgica, para implementar la sugerencia anterior, necesariamente debe utilizarse un microcontrolador con mayor poder de computo (como el ofrecido por los micrcocontroladores de la familia ARM) que el utilizado en la solucin propuesta en el presente trabajo. Una funcionalidad futura que se puede sugerir es la integracin del sistema propuesto con otras redes, similar a lo que ocurre con CAN y LIN. La implementacin de dispositivos que funcionen como puente entre el sistema de comunicaciones PLC y otro tipo de red, contribuye en la adopcin progresiva de sta tecnologa en aplicaciones comerciales. Adems toda nueva tecnologa al comienzo es costosa de implementar, por lo cual al comienzo no muchos dispositivos la adoptan, entonces el disponer de algunos dispositivos puente con otras redes que ofrezcan soluciones de interconexin ms econmicas resultan en una propuesta razonable. El modelo de implementacin de cinco capas dentro del modem PLC y dos en el dispositivo cliente en un futuro puede ser replanteado, disponiendo de microcontroladores con alto poder de computo (por ejemplo, ARM9) para implementar las siete capas en un slo dispositivo electrnico. Tambin puede ser viable si el dispositivo cliente es tan complejo que supere en varios rdenes de complejidad a las siete capas del sistema de comunicacin. En cuanto a las interfaces de uso del sistema de comunicacin planteado en ste trabajo, la implementacin incluye una interfaz C/C++ y una biblioteca de bloques Simulink para mostrar que se puede continuar el desarrollo por encima de la capa de aplicacin. Las interfaces mencionadas son de utilidad para simulaciones en una PC de dispositivos clientes virtuales, pero se limita a dos entornos. Una contribucin hacia el futuro puede ser plantear interfaces para distintos lenguajes de programacin e interfaces grficas para entornos de simulacin similares a Simulink.

192

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

7. Referencias
[Alcar07] Alcar H.: Power Line Communicacion en Argentina Revista Coordenadas, 2007 Alley C., Atwood K.: Ingeniera Electrnica 1ra. Edicin, 1968 Amrani O., Rubin A.: A new multiple access scheme for DC power line communications http://www.yamar.com/articles/A-new-multiple-access-scheme-forpowerline.pdf Atmel: 8-bit Microcontroller with 8K Bytes In-System Programmable Flash AT89S52 http://www.atmel.com/dyn/resources/prod_documents/doc1919.pdf Atmel: Flash Microcontroller Memory Organization http://www.atmel.com/dyn/resources/prod_documents/doc0498.pdf Atmel: 8-bit AVR Microcontroller with 8K Bytes In-System Programmable Flash ATmega8515 Atmega8515L http://www.atmel.com/dyn/resources/prod_documents/doc2512.pdf [AlleyAtwood68] [AmraniRubin]

[AT89S52]

[AT89CMemOrg]

[AT89mega8515]

[BenziFacchinettiCaprini08] Benzi F., Facchinetti T., Caprini D.: Powerline Protocols Review, evaluation and test for automotive applications, 2008 www.etec.polimi.it/emc-chapit/download/slides_Pavia_4_nov_2008.pdf [Bosch91] [D2B02] Robert Bosch GmbH, CAN Specification Version 2.0, 1991 Mercedes Benz: Domestic Digital Bus (D2B), 2002 http://www.mercedestechstore.com/pdfs/507%20Systems %20I/507%20HO%20D2B%20(ICC)%2010-30-02.pdf Mercedes Benz: Domestic Digital Bus (D2B), 2004 http://www.mercedestechstore.com/pdfs/416_Telematics/416%20H O%20D2B%20(CooksonI)%2003-09-04.pdf Echelon: Introduction to the LonWorks Platform Revision 2, 1999 http://www.echelon.com/support/documentation/manuals/general/07 8-0183-01B_Intro_to_LonWorks_Rev_2.pdf

[D2B04]

[Echelon99]

FernandoArielBeunza79156

193

Tesis de Grado en Ingeniera Informtica [FlexRay] UPC (Universidad Politcnica de Catalua): El Protocolo FlexRay http://upcommons.upc.edu/pfc/bitstream/2099.1/6115/4/2.%20El %20protocolo%20Flexray.pdf Exordio: HF-Drahtfunk (Radio por cable) http://www.exordio.com/1939-1945/civilis/telecom/hfdrahtfunk.html Home Plug Powerline Alliance: HomePlug 1.0.1 Specification, 2001 http://read.pudn.com/downloads114/ebook/479147/HOMEPLUG.pd f Home Plug Powerline Alliance: HomePlug AV White Paper, 2005 http://www.homeplug.org/tech/whitepapers/HPAV-WhitePaper_050818.pdf HomePlug Powerline Alliance: Home Plug Green PHY The Standard For In-Home Smart Grid Powerline Communications, 2010 http://www.homeplug.org/tech/whitepapers/HomePlug_Green_PHY _whitepaper_100614.pdf House P.: CEBus for the Masses http://www.integrasoft.ro/~barni/hpg/cjava/EIA-600%20Draft %20Specifications/CEBus%20For%20The%20Masses.pdf IEEE, IEEE P1901: Standard for Broadband over Power Line Networks: Medium Access Control and Physical Layer Specifications, 2010 http://grouper.ieee.org/groups/1901/ IEEE, IEEE 754: Standard for Binary Floating-Point Arithmetic, 1985 IEEE, IEEE 802.2: Lan/Man Logic Link Control, 1998 http://standards.ieee.org/getieee802/802.2.html ISO, ISO 7498-1, 1994 http://standards.iso.org/ittf/PubliclyAvailableStandards/s020269_IS O_IEC_7498-1_1994(E).zip

[HFDrahtfunk]

[HomePlug1.0]

[HomePlugAV]

[HomePlugGP]

[House]

[IEEEP1901]

[IEEE754]

[IEEE802.2]

[ISO74981]

194

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica [ISO/IEC149081] ISO, ISO/IEC 14908-1, Open Data Communication in Building Automation, Controls and Building Management Control Network Protocol Part 1: Protocol Stack, 1999 http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.h tm?csnumber=56523 Kaspar Z.: Power-Line Communication - Regulation Introduction, PL Modem Implementation and Possible Application http://www.urel.feec.vutbr.cz/ra2007/archive/ra2002/pdf/41.pdf Leen G., Heffernan D., Dunne A.: Digital Networks in Automotive Vehicle http://nicozone.free.fr/206/VAN/fp16.pdf LIN Consortium: LIN Specification Package Revision 2.2, 2010 http://www.lin-subbus.org/ Wikipedia: Linjesender http://en.wikipedia.org/wiki/Linjesender Maryanka Y.: Wiring Reduction by Battery Power Line Communications, 2000 http://www.yamar.com/articles/Wiring-reduction-by-DC-powerlinecommunication.pdf Montoya L.: Power Line Communications Performance Overview of the Physical Layer of Available protocols, 2006 http://masters.donntu.edu.ua/2006/kita/avramenko/library/lib9a.pdf Mercedes Benz: MOST System, 2004 http://www.mercedestechstore.com/pdfs/416_Telematics/416%20H O%20MOST%20%28CooksonI%29%2007-01-04.pdf MOST: MOST Specification Rev. 3.0 E2, 2010 http://www.mostcooperation.com/publications/Specifications_Organ izational_Procedures/index.html?doc=4425&dir=291 Oliver J.: Implementing the J1850 Protocol http://download.intel.com/design/intarch/papers/j1850_wp.pdf Oppenheim A., Willsky A.: Seales y Sistemas 2da. Edicin, 1997

[Kaspar]

[LeenHeffernanDunne]

[LIN10]

[Linjesender]

[Maryanka00]

[Montoya06]

[MOST04]

[MOST10]

[Oliver]

[OppenheimWillsky97]

FernandoArielBeunza79156

195

Tesis de Grado en Ingeniera Informtica [Paret05] Paret D.: Multiplexed Networks for Embbeded Systems CAN, LIN, Flexray, Safe-by-Wire..., 2005 http://books.google.com.ar/books? id=GfY38U8s3DIC&printsec=frontcover&hl=es#v=onepage&q&f=f alse UPS (Universidad Politcnica Salesiana): Investigacin y Anlisis de la Tecnologa PLC desde la Perspectiva del Mercado Ecuatoriano http://dspace.ups.edu.ec/bitstream/123456789/539/4/CAPITULO2.p df Rey S.: Introduction to LIN (Local Interconnect Network), 2003 http://rs-rey.pagesperso-orange.fr/electronic_ressources/Ressources/ Networks/LIN/LIN_bus.pdf Reuss H.: Extended Frame Format - A New Option of the CAN Protocol, 1993 http://cst.mi.fuberlin.de/projects/ScatterWeb/moduleComponents/CanBus_CAN2.p df USC (University of Southern California): Internet Protocol DARPA Internet Program Protocol Specification, 1991 http://www.ietf.org/rfc/rfc791.txt USC (University of Southern California): Transport Control Protocol DARPA Internet Program Protocol Specification, 1991 http://www.ietf.org/rfc/rfc793.txt Plummer D.: Ethernet Address Resolution Protocol, 1982 http://www.ietf.org/rfc/rfc826.txt SAE (Society of Automotive Engineers): SAE Standard J1850 Class B Data Communication Network Interface, 1994 www.autoelectric.cn/discuz/attachment.php?aid=6 Stallings W.: Data and Computer Comunications 5th. Edition, 1997 Strang T., Rckl M.: Vehicle Networks Controller Area Network (CAN) http://www.sti-innsbruck.at/fileadmin/documents/vn-ws0809/02VN-CAN.pdf

[PLCEc]

[Rey03]

[Reuss93]

[RFC791]

[RFC793]

[RFC826]

[SAE94]

[Stallings97] [StrangRckl]

196

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica [Trnka05] Trnka M.: Power Line Communications in Automotive Industry, 2005 http://measure.feld.cvut.cz/usr/doctoral/Trnka/teze.pdf Trnka M.: Optimization of the Data Transmissions over DC Power Lines, 2006 http://measure.feld.cvut.cz/usr/doctoral/Trnka/thesis.pdf Trnka M.: Optimization of the Data Transmissions over DC Power Lines, 2006 http://www3.fs.cvut.cz/web/fileadmin/documents/12241BOZEK/publikace/2006/2006_020_01.pdf Trnka M. ,Purkert M.: Development System for Communications over DC Power Lines, 2005 http://measure.feld.cvut.cz/usr/doctoral/Trnka/appel05.pdf Tropeano F.: Introduccin al Procesamiento y Transmisin de datos, 2003 PCS (Power Control Systems): The UPB System Description Version 1.1, 2003 http://www.smarthomeusa.com/Common/UPB/UPBdescription.pdf Verssimo P., Rodrigues L.: Distributed Systems for Systems Architects, 2001 Wense H.: Introduction to LIN, 2000 http://www.linsubbus.org/downloads/publications/introduction_to_lin.pdf EuroX10: Teoria da Transmisso de Sinais X-10 http://www.eurox10.com/Content/X10SignalTheory.htm X10 POWERHOUSE, Technical Note The X-10 POWERHOUSE Power Line Interface Model # PLC513 and Two-Way Power Line interface # TW523 ftp://ftp.x10.com/pub/manuals/technicalnote.pdf Zeltwanger H.: Introduction into CAN physical and data link layer http://www.can-expo.ru/files/physical.pdf

[Trnka061]

[Trnka062]

[TrnkaPurkert05]

[Tropeano03]

[UPB]

[VerssimoRodrigues01]

[Wense00]

[X10SignalTheory]

[X10TechNote]

[Zeltwanger]

FernandoArielBeunza79156

197

Tesis de Grado en Ingeniera Informtica

198

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Apndice A: Implementacin del hardware del modem PLC


En el ste apndice se describe y detalla la implementacin de cada uno de los componentes que conforman el hardware del prototipo de modem PLC construido para evaluar el funcionamiento de sistema propuesto en el presente trabajo

A.1. Organizacin del hardware


Debido a que el modem PLC implementado se trata de un prototipo, no se ve la necesidad de implementar el mismo en una nica plaqueta, lo cual evita ciertos problemas de interferencia entre los componentes electrnicos al no encontrarse concentrados en un espacio reducido. Adems, no es el objetivo del presente trabajo, realizar un dispositivo comercial en donde se exige la miniaturizacin. Por stos motivos la mejor forma de implementar el modem PLC es dividiendo las principales funcionalidades en mdulos separados (cada uno de stos corresponde a una plaqueta diferente) interconectados entre s para conformar un nico dispositivo. La organizacin propuesta permite separar los circuitos puramente analgicos, de los mixtos (digital/analgico) y de los puramente digitales. Adems cada mdulo trabaja con seales de distintos rangos de frecuencia. El mdulo analgico es puramente analgico y trabaja con seales de alta frecuencia por encima de 10 MHz. En cambio el mdulo de procesamiento de seales presenta una combinacin de partes analgicas y digitales, y las seales que procesa presentan frecuencias de rango intermedio por debajo de 5 MHz. El mdulo de procesamiento es puramente digital y trabaja con seales digitales con frecuencias por debajo de 1 MHz. sta organizacin permite tambin continuar investigando y desarrollando el tema tratado por ste trabajo, ya que pueden proponerse nuevas implementaciones de cada mdulo por separado, por ejemplo se puede mejorar la tecnologa de implementacin del mdulo analgico sin alterar los restantes mdulos, o bien mejorar la codificacin de la informacin sin alterar el mdulo analgico y el mdulo de procesamiento, o tambin aumentar la capacidad de procesamiento de mensajes del mdulo de procesamiento sin alterar los otros mdulos.

Figura A1. Diagrama de organizacin del hardware.

Los mdulos constituyentes del modem PLC prototipo (figura A1), se describe a continuacin:

Mdulo analgico: se compone de un Filtro, un Transmisor y un Receptor.

FernandoArielBeunza79156

199

Tesis de Grado en Ingeniera Informtica El Filtro consiste en un filtro pasivo que rechaza la banda de frecuencias utilizada para transmitir la informacin. Entrega por un lado la seal de potencia utilizada para alimentacin libre de ruido, y por otro, la seal de informacin, en forma separada. El Transmisor se encuentra constituido por un amplificador de entrada, un convertidor de frecuencias, un amplificador de salida y un circuito de acoplamiento. La seal de informacin es filtrada y amplificada por el amplificador de entradas. Luego la seal resultante es trasladada en frecuencia por el convertidor de frecuencias. La resultante de la conversin de frecuencias es amplificada por el amplificador de salida que se encarga de repetir la misma seal de entrada con la fuerza suficiente para propagarse por la red PLC. El circuito de acoplamiento se encarga de acoplar la salida del amplificador de salida con la red de potencia. El Receptor se encuentra constituido por un circuito de desacomplamiento, un amplificador de entrada, un convertidor de frecuencias y un amplificador de salida. El circuito de desacomplamiento filtra la seal de potencia, dejando solamente la seal con la informacin que es amplificada y filtrada por el amplificador de entrada. La seal resultante es convertida en frecuencia por el convertidor de frecuencias, y la seal de salida de dicho convertidor es filtrada y amplificada por el amplificador de salida.

Mdulo de procesamiento de seal: se compone de un microcontrolador dedicado al procesamiento de seales. Dicho microcontrolador es el encargado de sintetizar la seal de informacin, por medio de un DAC, que es tomada por el Transmisor del mdulo analgico y de detectar la informacin contenida en la seal proporcionada por el Receptor del mdulo analgico, por medio de un ADC. Dicha seal es retardada y posteriormente multiplicada por la seal sin retardar. La seal resultante de la multiplicacin es procesada por un integrador que acta como filtro pasabajos resultando a la salida de ste ltimo una seal donde se puede detectar la informacin contenida en la seal original. Mdulo de Procesamiento: se compone de un microcontrolador dedicado al procesamiento de mensajes. Dicho microcontrolador se encarga de ejecutar la lgica relacionada con las capas de enlace, red, transporte y sesin del modelo OSI. El microcontrolador de procesamiento interacta con otros dispositivos por medio de una interfaz serial de comunicaciones. Mdulo de Adaptacin RS232: se trata de un mdulo opcional que permite interconectar el modem PLC a una PC mediante un puerto serie. El mdulo de procesamiento provee de una interfaz serial de comunicaciones que permite la interconexin con otros dispositivos con ste tipo de interfaz sin necesidad de ninguna adaptacin. Para el caso de la PC es necesario un hardware adicional para adaptar las seales de la PC con las del mdulo de procesamiento.

Se debe notar que no existe ningn mdulo referido a la alimentacin del modem PLC, debido a que la funcin de fuente de alimentacin se encuentra distribuida entre los distintos mdulos, es decir que cada mdulo posee su propia fuente de alimentacin para independizar elctricamente a cada mdulo para evitar interferencias que hagan al mal funcionamiento de los mismos.

200

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

A.2. Implementacin del mdulo analgico


La implementacin de los circuitos constituyentes del mdulo analgico son similares a los detallados en el Apndice B (Simulacin del mdulo analgico). Pueden variar algunos componentes utilizados debido a que fsicamente no se comportan como indicaban los resultados de las simulaciones. En la primer pgina se puede observar las interfaz del mdulo analgico con la red de PLC y el mdulo de procesamiento de seales. En la segunda pgina se detalla circuito de alimentacin del mdulo analgico. En la tercer pgina se pueden observar los circuitos constituyentes del Transmisor (amplificador de entrada, oscilador, convertidor de frecuencias, amplificador de salida y circuito de acoplamiento). Finalmente en la cuarta pgina se pueden observar los circuitos que conforman el Receptor (circuito de desacoplamiento, amplificador de entrada, oscilador, convertidor de frecuencias, amplificador de salida).

FernandoArielBeunza79156

201

Tesis de Grado en Ingeniera Informtica

202

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

203

Tesis de Grado en Ingeniera Informtica

204

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

205

Tesis de Grado en Ingeniera Informtica

206

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

A.3. Implementacin del mdulo de procesamiento de seales


La implementacin de los circuitos constituyentes del mdulo procesamiento de seales son similares a los detallados en el Apndice B (Simulacin del mdulo de procesamiento de seales). Pueden variar algunos componentes utilizados debido a que fsicamente no se comportan como indicaban los resultados de las simulaciones. En la primer pgina se puede observar las interfaz del mdulo procesamiento de seales con el mdulo analgico y el mdulo de procesamiento. En la segunda pgina se detalla circuito de alimentacin del mdulo de procesamiento de seales. En la tercer pgina se puede observar el procesador de seales y el oscilador. En la cuarta pgina se detalla el DAC y el amplificador de salida. En la quinta pgina se puede observar el amplificador de entrada y el ADC. Finalmente en la sexta pgina se pueden el integrador y el sintetizador del nivel de umbral.

FernandoArielBeunza79156

207

Tesis de Grado en Ingeniera Informtica

208

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

209

Tesis de Grado en Ingeniera Informtica

210

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

211

Tesis de Grado en Ingeniera Informtica

212

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

213

Tesis de Grado en Ingeniera Informtica

A.4. Implementacin del mdulo de procesamiento


El mdulo de procesamiento se encuentra constituido un microcontrolador dedicado a todas las funcionalidades del modem PLC referidas al procesamiento de mensajes, salvo el procesamiento de seales que es realizado en el mdulo mencionado anteriormente. Este microcontrolador, necesita tener la posibilidad de expandir su memoria de cdigo y datos para poder contener el firmware con las capas de enlace, red, transporte y sesin del modelo OSI; resultando ms adecuada la utilizacin del microcontrolador 8052 AT89S52. Junto con el microcontrolador dedicado al procesamiento de mensajes se implementa un banco de memoria comn para cdigo y datos, en donde se utiliza un sector de la misma para datos y otro para cdigo. La memoria de datos se implementa con una memoria RAM de 32KB, ya que los datos no necesitan persistir en el tiempo; mientras que la memoria de cdigo se implementa con una memoria EEPROM, tambin de 32KB. A pesar que el microcontrolador AT89S52 ofrece la posibilidad de trabajar con bancos de memoria separados (cdigo y datos), en este caso se unifican ambos en un nico banco para permitir que el firmware cargador pueda utilizar a toda la memoria como memoria de datos, y poder llevar a cabo su tarea principal que es la carga del firmware del modem PLC, que para el cargador no son ms que datos que deben ser escritos en el sector de memoria no voltil. El mencionado firmware cargador se encuentra alojado en la memoria de cdigo interna del microcontrolador, ya que el AT89S52 permite trabajar con su memoria interna y el banco externo en forma simultnea, permitiendo dejar totalmente libre la memoria no voltil del banco para el firmware del modem PLC. Otra funcionalidad del cargador es permitir la ejecucin del firmware del modem PLC, ya que cuando se enciende el modem, lo primero que se ejecuta es el cargador, que mediante un comando de ste, se pasa a ejecutar el firmware del modem PLC, alojado en la memoria no voltil. Firmware Cargador RAM de datos 0x0000 0x1FFF 0x2000 0x7FFF 0x8000 Firmware Modem PLC 0xFFFF
Figura A2. Organizacin del banco de memoria (vista por el firmware cargador).

214

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

0x0000 RAM de datos 0x7FFF 0x8000 Firmware Modem PLC 0xFFFF


Figura A3. Organizacin del banco de memoria (vista por el firmware del modem PLC).

En la figuras A2 y A3, se pueden observar las organizaciones de memoria vistas desde el punto de vista del firmware cargador y del firmware del modem PLC, en donde el rea sombreada corresponde al cdigo que se ejecuta en ambos casos. Desde el punto de vista del firmware cargador, los primeros 8KB corresponden a su cdigo, luego le siguen 24KB de memoria RAM que no tiene ninguna utilidad (ya que el cargador trabaja con la memoria de datos interna del microcontrolador) y finalmente se ubican 32KB de memoria no voltil en donde el cargador aloja el firmware del modem PLC. Cuando el firmware cargador le pasa el control de ejecucin al firmware del modem PLC, la configuracin cambia a 32KB de memoria RAM voltil para datos y 32KB de memoria no voltil donde reside el firmware del modem PLC. Finalmente, el microcontrolador provee una interfaz de comunicacin serial que permite la interaccin con otros dispositivos. Fsicamente la interfaz trabaja con niveles de tensin compatibles con TTL lo que permite la interconexin directa con otros microcontroladores de otros dispositivos si necesidad de interponer un adaptador. En el caso de establecer una conexin con una PC, es necesario interponer el mdulo de adaptacin RS232 que realiza el ajuste de niveles de tensin entre la PC y el mdulo de procesamiento. A continuacin se detalla el esquema del mdulo de procesamiento en donde se muestran cada uno de los componentes descriptos con anterioridad. En la primer pgina se pueden observar la fuente de alimentacin, la interfaz de comunicacin con el mdulo de procesamiento de seal y la interfaz de comunicacin con el dispositivo cliente. En la segunda pgina se puede observar el microcontrolador junto a su reloj. Por ltimo en la tercer pgina se puede observar la composicin del banco de memoria.

FernandoArielBeunza79156

215

Tesis de Grado en Ingeniera Informtica

216

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

217

Tesis de Grado en Ingeniera Informtica

218

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

A.5. Implementacin del mdulo de adaptacin RS232


Como se hizo mencin en el tratamiento del mdulo de procesamiento, ste posee una interfaz de comunicacin serial para interactuar con otros dispositivos que pueden ser otros microcontroladores o una PC. Para el caso de ste ltimo es necesario introducir un adaptador debido a que los niveles de tensin utilizados por ambos dispositivos son distintos. La finalidad de ste mdulo es justamente la adaptacin de niveles de tensin y no posee ninguna otra funcin, lo cual resulta en un hardware simple, que es un opcional, ya que si el modem PLC no necesita ser conectado a una PC, no es necesario que tenga este mdulo adaptador. A continuacin se detalla el esquema del mdulo de adaptacin RS232 en donde se muestran cada uno de los componentes constitutivos.

FernandoArielBeunza79156

219

Tesis de Grado en Ingeniera Informtica

220

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Apndice B: Simulacin del hardware del modem PLC


En el ste apndice se describe y detalla la implementacin de cada uno de los componentes que conforman el hardware del modem PLC utilizado para la realizacin de las simulaciones, empleadas para evaluar el comportamiento de algunos componentes dicho modem en situaciones controladas.

B.1. Organizacin del hardware


El modem PLC se encuentra constituidos de tres mdulos, cuya descripcin ms detallada se encuentra en el Apndice A. Debido a diferencias entre los componentes reales y los simulados, la implementacin de los circuitos presentan leves diferencias entre la implementacin utilizada para simulacin y la implementacin real. En el presente apndice se detalla la implementacin (para simulacin) del mdulo analgico y del mdulo de procesamiento de seales, que son los mdulos ms vinculados con los aspectos fsicos. El mdulo de procesamiento no es necesario implementarlo para simulacin porque en l reside todo la lgica del sistema que no es simulada.

B.2. Implementacin del mdulo analgico


Los circuitos constituyentes del mdulo analgico que fueron simulados se enumeran a continuacin ordenados por orden de aparicin de los esquemas:

Esquema 1: Batera y seales de prueba. Proporcionan la alimentacin y las seales de estmulo para los circuitos bajo prueba. Esquema 2: Fuente de alimentacin. Proporciona alimentacin estable a los circuitos bajo prueba. Esquema 3: Oscilador. Genera una seal con la frecuencia necesaria para el funcionamiento de los Convertidores de frecuencias utilizados en el Transmisor y en el Receptor. Esquema 4: Transmisor. Se compone de un Amplificador de entrada, un Convertidor de frecuencias, un Amplificador de salida y un Circuito de acoplamiento. El Amplificador de entrada se encarga de limitar en frecuencia la seal de entrada a ser transmitida y amplificarla para que pueda ser modulada por el Convertidor de Frecuencias. El Convertidor de frecuencias consiste en un modulador VSB-SC, que se encarga de trasladar las seales de entrada a un rango de frecuencias superior a partir de la frecuencia generada por el Oscilador. El Amplificador de salida se encarga de repetir la seal generada por el Convertidor de frecuencias con la suficiente potencia para que la misma viaje por la red de potencia. El Circuito de acoplamiento es un circuito compuesto por elementos pasivo que bloquea el ingreso de la componente continua de potencia a la 221

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica salida del Amplificador de salida, a la vez que permite el paso de la seal generada por el Amplificador de salida hacia la red de potencia.

Esquema 5: Receptor. Se compone de un Circuito de desacoplamiento, un Amplificador de entrada, un Convertidor de frecuencias y un Amplificador de salida. El Circuito de desacoplamiento es un circuito compuesto por elementos pasivos que rechaza la componente continua de potencia y deja pasar a la seal de informacin. El Amplificador de entrada se encarga de amplificar dicha seal para que pueda ser demodulada por el Convertidor de frecuencias. El Convertidor de frecuencias consiste en un demodulador VSB-SC, que traslada la seal recibida del Amplificador de entrada a un rango de frecuencias manejable por el microcontrolador a partir de la frecuencia de traslacin generada por el Oscilador. Finalmente el Amplificador de salida se encarga de amplificar la seal generada por el Convertidor de frecuencias y eliminar el ruido generado por ste ltimo.

222

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

223

Tesis de Grado en Ingeniera Informtica

224

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

225

Tesis de Grado en Ingeniera Informtica

226

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

227

Tesis de Grado en Ingeniera Informtica

B.3. Implementacin del mdulo de procesamiento de seales


Los circuitos constituyentes del mdulo de procesamiento de seales que fueron simulados se enumeran a continuacin ordenados por orden de aparicin de los esquemas:

Esquema 1: Estmulo. Proporciona la alimentacin y las seales de estmulo para los circuitos bajo prueba. Esquema 2: Alimentacin. Proporciona alimentacin estable a los circuitos bajo prueba. Esquema 3: Microcontrolador I. Simula el algoritmo, que se ejecuta dentro del microcontrolador procesador de seal, encargado codificar la trama de bits suministrada utilizando codificacin diferencial (modulacin DBPSK) y de sintetizar la seal que transporta a dicha trama de bits codificada. Esquema 4: DAC. Se encarga de generar la seal analgica correspondiente a la sintetizada por el Microcontrolador I y amplificarla. El DAC utilizado es de 4 bits. Esquema 5: Canal de transmisin. Simula el canal de transmisin utilizado para enviar la seal con la informacin. Dicho canal incluye del mdulo analgico y la red de potencia. Esquema 6: ADC. Se encarga de amplificar la seal recibida para su posterior digitalizacin. El ADC utilizado es de 1 bit. Esquema 7: Microcontrolador II. Simula el algoritmo, que se ejecuta dentro del microcontrolador procesador de seal, encargado de leer la salida del ADC, implementar en retardo de seal y realizar la multiplicacin entre la seal de leda directamente y la seal retardada (demodulacin DBPSK). Esquema 8: Integrador. Implementa un filtro pasabajos que trabaja con Microcontrolador II para implementar el demodulador DBPSK. La seal resultante contiene la trama de bits originalmente transmitida. Esquema 9: Microcontrolador III. Simula el algoritmo, que se ejecuta dentro del microcontrolador procesador de seal, encargado de detectar el valor de cada bit de la trama recibida del integrador conforme a un umbral de referencia determinado tambin por dicho algoritmo.

228

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

229

Tesis de Grado en Ingeniera Informtica

230

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

231

Tesis de Grado en Ingeniera Informtica

232

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

233

Tesis de Grado en Ingeniera Informtica

234

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

235

Tesis de Grado en Ingeniera Informtica

236

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

237

Tesis de Grado en Ingeniera Informtica

238

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Apndice C: Cdigo fuente


En el presente apndice se describe la organizacin del cdigo fuente que constituye el sistema desarrollado como propuesta en ste trabajo, as como tambin se detalla cada componente de dicho cdigo fuente.

C.1. Organizacin del cdigo fuente


El cdigo fuente se compone de cuatro partes correspondientes al driver e interfaces del modem PLC, al firmware del modem PLC, al firmware del procesador de seales y al firmware cargador. Cada una de stas partes se encuentra organizada en mdulos, cada uno constituido por un archivo .h donde se declaran las primitivas y un .c donde se implementan las mismas. Los mdulos constituyentes del driver e interfaces del modem PLC corresponden a las capas de presentacin y aplicacin del modelo OSI, que se encuentran implementadas dentro de los dispositivos clientes (reales o virtuales), y vara su implementacin segn la plataforma sobre la cual se trabaje. Para la plataformas Windows y Linux, adems de implementarse la capa de presentacin y la capa de aplicacin, se implementan interfaces de acceso a la capa de enlace y la capa fsica para la realizacin de pruebas, y desarrollo de futuras aplicaciones. Para el caso de la plataforma AT89X5X, solamente se implementa la capa de presentacin y de aplicacin. Los mdulos que conforman el firmware del modem PLC, corresponden a parte de la capa fsica y las capas de enlace, red, transporte y sesin del modelo OSI. ste firmware se ubica fsicamente en la memoria de cdigo externa del microcontrolador de procesamiento. El firmware del procesador de seales implementa parte de la capa fsica no implementada en el firmware del modem PLC, y se encuentra ubicado fsicamente en un microcontrolador dedicado exclusivamente a la tarea del procesamiento de seales de informacin. Por ltimo el firmware cargador es una utilidad que permite cargar el firmware del modem PLC en la memoria de cdigo externa del microcontrolador de procesamiento. Dicho cargador se encuentra alojado en la memoria interna de cdigo del microcontrolador de procesamiento.

FernandoArielBeunza79156

239

Tesis de Grado en Ingeniera Informtica

Capa de aplicacin
(varia segn plataforma)

Capa de presentacin
(varia segn plataforma)

Interfaz RS232 (dispositivo cliente)


(varia segn plataforma)


Interfaz RS232 (mdulo de procesamiento)
serial.h serial.c modem.c

Capa de sesin
sp.h sp.c

Capa de transporte
tp.h tp.c

Capa de red
net.h net.c

Capa de enlace Resolucin de direcciones (ARP)


arp.h arp.c mac.h mac.c

Control de lgica de enlace (LLC)


llc.h llc.c

Control de acceso al medio (MAC) Capa fsica (mdulo de procesamiento)


phy.h phy.c


Capa fsica (mdulo de procesamiento de seales)
phy.h phy.c main.c

Figura C1. Diagrama de organizacin de cdigo.

En la figura C1 se detalla la distribucin de cada uno de los archivos del cdigo fuente dentro del modelo de capas. Se puede observar que las capas se encuentran distribuidas en tres grupos asociados al lugar donde se encuentran implementadas (mdulo de procesamiento de seales, mdulo de procesamiento y dispositivo cliente).
Capa de aplicacin
ap.h ap.c

Capa de presentacin
pp.h pp.c

Interfaz RS232 (dispositivo cliente)


serial.h serial.c

Figura C2. Diagrama de organizacin de cdigo del dispositivo cliente para plataforma AT89X5X.

En la figura C2 se puede observar la distribucin de cada uno de los archivos del cdigo fuente correspondiente a la capa de presentacin y la capa de aplicacin para la plataforma

240

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica AT89X5X. Debajo la capa de presentacin existe una interfaz RS232 encargada de las comunicaciones entre el modem PLC y el dispositivo cliente.
Capa de aplicacin
modplcap.h modplcap.c

Capa de presentacin
modplcpp.h modplcpp.c

Interfaz capa de enlace


modplcdl.h modplcdl.c

Interfaz capa fsica


modplcphy.h modplcphy.c

Interfaz capa de sesin


modplcsp.h modplcsp.c

Interfaz RS232 Driver (dispositivo cliente)


serial.h serial.c modplc.h modplc.c modsp.h modsp.c moddl.h moddl.c modphy.h modphy.c moddrv.h moddrv.c modem_driver.c

Figura C3. Diagrama de organizacin de cdigo del dispositivo cliente para plataformas Windows y Linux.

En la figura C3 se detalla la distribucin de cada uno de los archivos del cdigo fuente correspondiente a la capa de presentacin y la capa de aplicacin para las plataformas Windows y Linux; adems de las interfaces de acceso a la capa de enlace y a la capa fsica. Tanto la pila de capas de presentacin y aplicacin, como las interfaces a capa de enlace y capa fsica se comunican con el modem PLC por medio del driver del mismo.

C.2. Especificacin del cdigo fuente de las bibliotecas de uso del modem PLC (plataforma AT89X5X)
En esta seccin se detalla el cdigo fuente de las bibliotecas de uso del modem PLC compuesto por los siguientes archivos:

Archivo config.h: en este archivo se definen parmetros de configuracin de las bibliotecas de uso del modem PLC que no pueden ser modificados. Archivo modplcap.h: en este archivo se declaran las primitivas correspondientes al manejo de la capa de aplicacin. Archivos modplcap*.c: en estos archivos se encuentran implementadas las primitivas declaradas en el archivo modplcap.h. Archivo modplcpp.h: en este archivo se declaran las primitivas correspondientes al manejo de la capa de presentacin. Dichas primitivas brindan la capacidad de trabajar con estructuras de datos independientes de la plataforma. Archivos modplcpp*.c: en estos archivos se encuentran implementadas las primitivas declaradas en el archivo modplcpp.h.

FernandoArielBeunza79156

241

Tesis de Grado en Ingeniera Informtica

Archivo modplcsp.h: en este archivo se declaran las primitivas correspondientes al interfaz con la capa de sesin. Dichas primitivas brindan un conjunto de funcionalidades que permiten la comunicacin con la capa de sesin implementada en el modem PLC. Archivos modplcsp*.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo modplcsp.h. Archivo serial.h: en este archivo se declaran primitivas con funcionalidades referentes a la entrada y salida va UART. Archivo serial.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo serial.h.

C.2.1. Archivo config.h


/* config.h Definicin de parmetros de configuracin. */

#if !defined(__CONFIG_H__) #define __CONFIG_H__

/* Interfaz del modem PLC. */ /* Tipos de prompt utilizados. */ #define MODPLC_INITPROMPT #define MODPLC_LAYPROMPT #define MODPLC_NORMPROMPT #define MODPLC_PARAMPROMPT /* Tipos de reset. */ #define MODPLC_NORMRESET #define MODPLC_PARAMRESET /* Capas de acceso. */ #define MODPLC_PHYSICALLAYER #define MODPLC_DATALINKLAYER #define MODPLC_SESSIONLAYER

'#' '?' '$' '>'

'0' '$'

'1' '2' '3'

/* Capa de sesin. */ /* Intervalo de tiempo en milisegundos de verificacin de mensaje recibido. */ #define MODPLCSP_POLLINTERVAL 250 /* Cdigo de operaciones de la capa de sesin. */ #define MODPLCSP_RESET #define MODPLCSP_PUBLISH #define MODPLCSP_SUBSCRIBE #define MODPLCSP_LEAVE #define MODPLCSP_SEND #define MODPLCSP_RECEIVE #define MODPLCSP_POLL #define MODPLCSP_GETPAYLOADSIZE

'0' '1' '2' '3' '4' '5' '6' '7'

#endif

242

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

C.2.2. Archivo modplcap.h


/* modplcap.h: Declaracin de funciones referentes a la capa de aplicacin del modem PLC. */

#if !defined(__MODPLCAP_H__) #define __MODPLCAP_H__

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica que se encuentre definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #warning "MODPLCAP_MSGSIZE not defined" #define MODPLCAP_MSGSIZE 0 #endif #define MODPLCPP_MSGSIZE MODPLCAP_MSGSIZE

/* Archivos includos necesarios. */ #include "modplcpp.h"

/* Definicin de tipos. */ /* Identificador de grupo. */ typedef unsigned char modplcap_grpid; /* Identificador de mensaje. */ typedef unsigned short int modplcap_msgid; /* Tipo de campo. */ typedef unsigned char modplcap_ftype; /* Tipo mensaje. */ typedef struct { modplcap_msgid msgid; modplcpp_msg msg; } modplcap_msg; /* Manejador de capa de aplicacin. */ #if defined SDCC_MODEL_SMALL typedef struct { __data modplcpp_hd *modpphd; __data modplcap_msg *recvbuff; void (*recfun) (__data void *, __data modplcap_msg *, __data void *) __reentrant; __data void *param;

/* Identificador de mensaje. */ /* Mensaje. */

/* Manejador de interfaz con la capa de sesin del modem PLC. */ /* Puntero al buffer de recepcin. */

/* Funcin manejadora de mensajes recibidos. */ /* Parmetros para la funcin manejadora de mensajes recibidos. */

} modplcap_hd; #else typedef struct { modplcpp_hd *modpphd;

/* Manejador de interfaz con la capa de sesin del modem PLC. */

FernandoArielBeunza79156

243

Tesis de Grado en Ingeniera Informtica


modplcap_msg *recvbuff; void (*recfun) (void *, modplcap_msg *, void *) __reentrant; void *param; /* Puntero al buffer de recepcin. */

/* Funcin manejadora de mensajes recibidos. */ /* Parmetros para la funcin manejadora de mensajes recibidos. */

} modplcap_hd; #endif

/* Definicin de constantes. */ /* Tipos de datos. */ #define MODPLCAP_NULLTYPE #define MODPLCAP_CHARTYPE #define MODPLCAP_SINT8TYPE #define MODPLCAP_UINT8TYPE #define MODPLCAP_SINT16TYPE #define MODPLCAP_UINT16TYPE #define MODPLCAP_SINT32TYPE #define MODPLCAP_UINT32TYPE #define MODPLCAP_FLOATTYPE

0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08

/* Declaracin de funciones pblicas. */ /* Funcin modplcap__init: Inicializa los recursos utilizados por la capa de aplicacin del modem PLC. */ #if defined SDCC_MODEL_SMALL __data modplcap_hd *modplcap__init(int, short int); #else modplcap_hd *modplcap__init(int, short int); #endif /* Funcin modplcap__init: Inicializa los recursos utilizados por la capa de aplicacin del modem PLC. */ #define modplcap_init(sid)\ modplcap__init(sid, MODPLCAP_MSGSIZE) /* Funcin modplcap_release: Libera los recursos utilizados por la capa de aplicacin del modem PLC. */ #if defined SDCC_MODEL_SMALL int modplcap_release(__data modplcap_hd *); #else int modplcap_release(modplcap_hd *); #endif /* Funcin modplcap_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ #if defined SDCC_MODEL_SMALL int modplcap_publish(__data modplcap_hd *, modplcap_grpid); #else int modplcap_publish(modplcap_hd *, modplcap_grpid); #endif /* Funcin modplcap_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ #if defined SDCC_MODEL_SMALL

244

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


int modplcap_subscribe(__data modplcap_hd *, modplcap_grpid); #else int modplcap_subscribe(modplcap_hd *, modplcap_grpid); #endif /* Funcin modplcap_leave: Desvincula el dispositivo del grupo de difusin especificado. */ #if defined SDCC_MODEL_SMALL int modplcap_leave(__data modplcap_hd *, modplcap_grpid); #else int modplcap_leave(modplcap_hd *, modplcap_grpid); #endif /* Funcin modplcap_newmsg: Crea un nuevo mensaje. */ #if defined SDCC_MODEL_SMALL int modplcap_newmsg(__data modplcap_hd *, __data modplcap_msg *, modplcap_grpid, modplcap_msgid); #else int modplcap_newmsg(modplcap_hd *, modplcap_msg *, modplcap_grpid, modplcap_msgid); #endif /* Funcin modplcap_copymsg: Crea un copia de un mensaje. */ #if defined SDCC_MODEL_SMALL int modplcap_copymsg(__data modplcap_msg *, __data modplcap_msg *); #else int modplcap_copymsg(modplcap_msg *, modplcap_msg *); #endif /* Funcin modplcap_putfield: Agrega un nuevo campo al mensaje. */ #if defined SDCC_MODEL_SMALL int modplcap_putfield(__data modplcap_msg *, modplcap_ftype, unsigned char, const __data void *); #else int modplcap_putfield(modplcap_msg *, modplcap_ftype, unsigned char, const void *); #endif /* Funcin modplcap_sendmsg: Enva un mensaje por medio de la capa de aplicacin. */ #if defined SDCC_MODEL_SMALL int modplcap_sendmsg(__data modplcap_msg *); #else int modplcap_sendmsg(modplcap_msg *); #endif /* Funcin modplcap_receivemsg: Recibe un mensaje por medio de la capa de aplicacin. */ #if defined SDCC_MODEL_SMALL int modplcap_receivemsg(__data modplcap_hd *, __data modplcap_msg *); #else int modplcap_receivemsg(modplcap_hd *, modplcap_msg *); #endif /* Funcin modplcap_getfield:

FernandoArielBeunza79156

245

Tesis de Grado en Ingeniera Informtica


Extrae un campo del mensaje. */ #if defined SDCC_MODEL_SMALL int modplcap_getfield(__data modplcap_msg *, __data modplcap_ftype *, __data unsigned char *, __data void *); #else int modplcap_getfield(modplcap_msg *, modplcap_ftype *, unsigned char *, void *); #endif /* Funcin modplcap_getgrpid: Devuelve el identificador de grupo del mensaje. */ #if defined SDCC_MODEL_SMALL modplcap_grpid modplcap_getgrpid(__data modplcap_msg *); #else modplcap_grpid modplcap_getgrpid(modplcap_msg *); #endif /* Funcin modplcap_getmsgid: Devuelve el identificador de mensaje. */ #if defined SDCC_MODEL_SMALL modplcap_msgid modplcap_getmsgid(__data modplcap_msg *); #else modplcap_msgid modplcap_getmsgid(modplcap_msg *); #endif /* Funcin modplcap_destroymsg: Destruye un mensaje. */ #if defined SDCC_MODEL_SMALL int modplcap_destroymsg(__data modplcap_msg *); #else int modplcap_destroymsg(modplcap_msg *); #endif /* Funcin modplcap_setbuffer: Define el buffer de recepcin. */ #if defined SDCC_MODEL_SMALL int modplcap_setbuffer(__data modplcap_hd *, __data modplcap_msg *); #else int modplcap_setbuffer(modplcap_hd *, modplcap_msg *); #endif /* Funcin modplcap_notify: Define una funcin manejadora de mensajes recibidos. */ #if defined SDCC_MODEL_SMALL int modplcap_notify(__data modplcap_hd *, void (*func)(__data modplcap_hd *, __data modplcap_msg *, __data void *), __data void *); #else int modplcap_notify(modplcap_hd *, void (*func)(modplcap_hd *, modplcap_msg *, void *), void *); #endif /* Funcin modplcap_poll: Verifica la llegada de un nuevo mensaje. */ #if defined SDCC_MODEL_SMALL int modplcap_poll(__data modplcap_hd *); #else int modplcap_poll(modplcap_hd *); #endif

246

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin modplcap_status: Devuelve el estado del modem PLC. */ #if defined SDCC_MODEL_SMALL int modplcap_status(__data modplcap_hd *); #else int modplcap_status(modplcap_hd *); #endif

#endif

C.2.3. Archivo modplcap__init.c


/* modplcap__init.c: Implementacin de la funcin modplcap__init de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdlib.h>

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcap.h"

/* Variables globales. */ volatile modplcap_hd __modplcap_hd__;

/* Implementacin de funciones pblicas. */ /* Funcin modplcap__init: Inicializa los recursos utilizados por la capa de aplicacin del modem PLC. */ #if defined SDCC_MODEL_SMALL __data modplcap_hd *modplcap__init(int sid, short int msgsize) #else modplcap_hd *modplcap__init(int sid, short int msgsize) #endif { /* Inicializa la interfaz de la capa de presentacindel modem PLC. */ __modplcap_hd__.modpphd = modplcpp__init(sid, msgsize); if (!__modplcap_hd__.modpphd) return NULL; /* Inicializa el buffer de recepcin. */ __modplcap_hd__.recvbuff = NULL; /* Inicializa la funcin manejadora de mensajes recibidos. */ __modplcap_hd__.recfun = NULL; /* Devuelve el manejador creado. */ return &__modplcap_hd__; }

FernandoArielBeunza79156

247

Tesis de Grado en Ingeniera Informtica

C.2.4. Archivo modplcap_release.c


/* modplcap_release.c: Implementacin de la funcin modplcap_release de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcap.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcap_release: Libera los recursos utilizados por la capa de aplicacin del modem PLC. */ #if defined SDCC_MODEL_SMALL int modplcap_release(__data modplcap_hd *hd) #else int modplcap_release(modplcap_hd *hd) #endif { /* Verifica que el manejador de capa de aplicacin del modem PLC exista. */ if (!hd) return 0; /* Libera los recursos utilizados por la capa de presentacin del modem PLC. */ return modplcpp_release(hd->modpphd); }

C.2.5. Archivo modplcap_publish.c


/* modplcap_publish.c: Implementacin de la funcin modplcap_publish de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcap.h"

248

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Implementacin de funciones pblicas. */ /* Funcin modplcap_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ #if defined SDCC_MODEL_SMALL int modplcap_publish(__data modplcap_hd *hd, modplcap_grpid grpid) #else int modplcap_publish(modplcap_hd *hd, modplcap_grpid grpid) #endif { /* Verifica que el manejador de capa de aplicacin del modem PLC exista. */ if (!hd) return 0; /* Registra el dispositivo como publicador del grupo de difusin especificado. */ return modplcpp_publish(hd->modpphd, (modplcap_grpid) grpid); }

C.2.6. Archivo modplcap_subscribe.c


/* modplcap_subscribe.c: Implementacin de la funcin modplcap_subscribe de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcap.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcap_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ #if defined SDCC_MODEL_SMALL int modplcap_subscribe(__data modplcap_hd *hd, modplcap_grpid grpid) #else int modplcap_subscribe(modplcap_hd *hd, modplcap_grpid grpid) #endif { /* Verifica que el manejador de capa de aplicacin del modem PLC exista. */ if (!hd) return 0; /* Registra el dispositivo como suscriptor del grupo de difusin especificado. */ return modplcpp_subscribe(hd->modpphd, (modplcpp_grpid) grpid); }

FernandoArielBeunza79156

249

Tesis de Grado en Ingeniera Informtica

C.2.7. Archivo modplcap_leave.c


/* modplcpa_leave.c: Implementacin de la funcin modplcap_leave de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcap.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcap_leave: Desvincula el dispositivo del grupo de difusin especificado. */ #if defined SDCC_MODEL_SMALL int modplcap_leave(__data modplcap_hd *hd, modplcap_grpid grpid) #else int modplcap_leave(modplcap_hd *hd, modplcap_grpid grpid) #endif { /* Verifica que el manejador de capa de aplicacin del modem PLC exista. */ if (!hd) return 0; /* Desvincula el dispositivo del grupo de difusin especificado. */ return modplcpp_leave(hd->modpphd, (modplcap_grpid) grpid); }

C.2.8. Archivo modplcap_newmsg.c


/* modplcap_newmsg.c: Implementacin de la funcin modplcap_newmsg de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcap.h"

/* Implementacin de funciones pblicas. */

250

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin modplcap_newmsg: Crea un nuevo mensaje. */ #if defined SDCC_MODEL_SMALL int modplcap_newmsg(__data modplcap_hd *hd, __data modplcap_msg *msg, modplcap_grpid grpid, modplcap_msgid msgid) #else int modplcap_newmsg(modplcap_hd *hd, modplcap_msg *msg, modplcap_grpid grpid, modplcap_msgid msgid) #endif { /* Verifica que el manejador de capa de aplicacin del modem PLC exista. */ if (!hd) return 0; /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Inicializa el mensaje. */ msg->msgid = msgid; if (msgid & 0x8000) { if (!modplcpp_newmsg(hd->modpphd, &(msg->msg), grpid, MODPLCPP_NOSECMSG)) return 0; } else { if (!modplcpp_newmsg(hd->modpphd, &(msg->msg), grpid, MODPLCPP_SECMSG)) return 0; } if (!modplcpp_putfield(&(msg->msg), MODPLCPP_UINT16TYPE, 1, &msgid)) return 0; return 1; }

C.2.9. Archivo modplcap_copymsg.c


/* modplcap_copymsg.c: Implementacin de la funcin modplcap_copymsg de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcap.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcap_copymsg: Crea un copia de un mensaje. */ #if defined SDCC_MODEL_SMALL int modplcap_copymsg(__data modplcap_msg *dest, __data modplcap_msg *src)

FernandoArielBeunza79156

251

Tesis de Grado en Ingeniera Informtica


#else int modplcap_copymsg(modplcap_msg *dest, modplcap_msg *src) #endif { /* Verifica que el puntero al mensaje original no sea nulo. */ if (!src) return 0; /* Verifica que el puntero a la copia del mensaje no sea nulo. */ if (!dest) return 0; /* Copia el contenido del mensaje. */ dest->msgid = src->msgid; return modplcpp_copymsg(&(dest->msg), &(src->msg)); }

C.2.10. Archivo modplcap_putfield.c


/* modplcap_putfield.c: Implementacin de la funcin modplcap_putfield de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcap.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcap_putfield: Agrega un nuevo campo al mensaje. */ #if defined SDCC_MODEL_SMALL int modplcap_putfield(__data modplcap_msg *msg, modplcap_ftype type, unsigned char count, const __data void *dat) #else int modplcap_putfield(modplcap_msg *msg, modplcap_ftype type, unsigned char count, const void *dat) #endif { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Agrega un nuevo campo al mensaje. */ return modplcpp_putfield(&(msg->msg), type, count, dat); }

C.2.11. Archivo modplcap_sendmsg.c


/* modplcap_sendmsg.c: Implementacin de la funcin modplcap_sendmsg de la capa de aplicacin del modem PLC.

252

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


*/

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcap.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcap_sendmsg: Enva un mensaje por medio de la capa de aplicacin. */ #if defined SDCC_MODEL_SMALL int modplcap_sendmsg(__data modplcap_msg *msg) #else int modplcap_sendmsg(modplcap_msg *msg) #endif { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Enva un mensaje. */ return modplcpp_sendmsg(&(msg->msg)); }

C.2.12. Archivo modplcap_receivemsg.c


/* modplcap_receivemsg.c: Implementacin de la funcin modplcap_receivemsg de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcap.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcap_receivemsg: Recibe un mensaje por medio de la capa de aplicacin. */ #if defined SDCC_MODEL_SMALL int modplcap_receivemsg(__data modplcap_hd *hd, __data modplcap_msg *msg) #else

FernandoArielBeunza79156

253

Tesis de Grado en Ingeniera Informtica


int modplcap_receivemsg(modplcap_hd *hd, modplcap_msg *msg) #endif { /* Variables. */ modplcpp_ftype type; /* Tipo de campo. */ unsigned char count; /* Multiplicidad del campo. */

/* Verifica el estado del modem PLC. */ if (!modplcap_status(hd)) return 0; /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Espera la llegada de un mensaje. */ while(!modplcap_poll(hd)); /* Recibe el mensaje. */ while(1) { if (!modplcpp_receivemsg(hd->modpphd, &(msg->msg))) break; if (!modplcpp_getfield(&(msg->msg), &type, &count, &(msg->msgid))) break; if (type != MODPLCPP_UINT16TYPE) break; if (count != 1) break; return 1; } modplcap_destroymsg(msg); return 0; }

C.2.13. Archivo modplcap_getfield.c


/* modplcap_getfield.c: Implementacin de la funcin modplcap_getfield de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcap.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcap_getfield: Extrae un campo del mensaje. */ #if defined SDCC_MODEL_SMALL int modplcap_getfield(__data modplcap_msg *msg, __data modplcap_ftype *type, __data unsigned char *count, __data void *dat) #else int modplcap_getfield(modplcap_msg *msg, modplcap_ftype *type,

254

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


unsigned char *count, void *dat) #endif { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Extrae un campo del mensaje. */ return modplcpp_getfield(&(msg->msg), type, count, dat); }

C.2.14. Archivo modplcap_getgrpid.c


/* modplcap_getgrpid.c: Implementacin de la funcin modplcap_getgrpid de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcap.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcap_getgrpid: Devuelve el identificador de grupo del mensaje. */ #if defined SDCC_MODEL_SMALL modplcap_grpid modplcap_getgrpid(__data modplcap_msg *msg) #else modplcap_grpid modplcap_getgrpid(modplcap_msg *msg) #endif { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Devuelve el identificador de grupo del mensaje. */ return modplcpp_getgrpid(&(msg->msg)); }

C.2.15. Archivo modplcap_getmsgid.c


/* modplcap_getmsgid.c: Implementacin de la funcin modplcap_getmsgid de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

FernandoArielBeunza79156

255

Tesis de Grado en Ingeniera Informtica


/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcap.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcap_getmsgid: Devuelve el identificador de mensaje. */ #if defined SDCC_MODEL_SMALL modplcap_msgid modplcap_getmsgid(__data modplcap_msg *msg) #else modplcap_msgid modplcap_getmsgid(modplcap_msg *msg) #endif { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Devuelve el identificador de mensaje. */ return msg->msgid; }

C.2.16. Archivo modplcap_destroymsg.c


/* modplcap_destroymsg.c: Implementacin de la funcin modplcap_destroymsg de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcap.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcap_destroymsg: Destruye un mensaje. */ #if defined SDCC_MODEL_SMALL int modplcap_destroymsg(__data modplcap_msg *msg) #else int modplcap_destroymsg(modplcap_msg *msg) #endif { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Destruye el mensaje. */

256

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


msg->msgid = 0; return modplcpp_destroymsg(&(msg->msg)); }

C.2.17. Archivo modplcap_setbuffer.c


/* modplcap_setbuffer.c: Implementacin de la funcin modplcap_setbuffer de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcap.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcap_setbuffer: Define el buffer de recepcin. */ #if defined SDCC_MODEL_SMALL int modplcap_setbuffer(__data modplcap_hd *hd, __data modplcap_msg *buffer) #else int modplcap_setbuffer(modplcap_hd *hd, modplcap_msg *buffer) #endif { /* Verifica el estado del modem PLC. */ if (!modplcap_status(hd)) return 0; /* Define el buffer de recepcin. */ hd->recvbuff = buffer; return 1; }

C.2.18. Archivo modplcap_notify.c


/* modplcap_notify.c: Implementacin de la funcin modplcap_notify de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdlib.h>

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif

FernandoArielBeunza79156

257

Tesis de Grado en Ingeniera Informtica

/* Archivos includos necesarios. */ #include "modplcap.h"

/* Declaracin de funciones privadas. */ #if defined SDCC_MODEL_SMALL static void __modplcap_procmsg__(__data modplcpp_hd *, __data modplcpp_msg *, __data void *) __reentrant; #else static void __modplcap_procmsg__(modplcpp_hd *, modplcpp_msg *, void *) __reentrant; #endif

/* Implementacin de funciones pblicas. */ /* Funcin modplcap_notify: Define una funcin manejadora de mensajes recibidos. */ #if defined SDCC_MODEL_SMALL int modplcap_notify(__data modplcap_hd *hd, void (*func)(__data modplcap_hd *, __data modplcap_msg *, __data void *), __data void *param) #else int modplcap_notify(modplcap_hd *hd, void (*func)(modplcap_hd *, modplcap_msg *, void *), void *param) #endif { /* Verifica que el manejador de capa de aplicacin del modem PLC exista. */ if (!hd) return 0; /* Define un manejador de mensajes recibidos. */ #if defined SDCC_MODEL_SMALL hd->recfun = (void (*)(__data void *, __data modplcap_msg *, __data void *)) func; #else hd->recfun = (void (*)(void *, modplcap_msg *, void *)) func; #endif if (!modplcpp_notify(hd->modpphd, __modplcap_procmsg__, hd)) { hd->recfun = NULL; return 0; } hd->param = param; return 1; }

/* Implementacin de funciones privadas. */ /* Funcin __modplcap_procmsg__: Procesa un mensaje recibido por medio de la capa de presentacin. */ #if defined SDCC_MODEL_SMALL static void __modplcap_procmsg__(__data modplcpp_hd *hd, __data modplcpp_msg *msg, __data void *param) __reentrant #else static void __modplcap_procmsg__(modplcpp_hd *hd, modplcpp_msg *msg, void *param) __reentrant #endif { /* Variables. */ #if defined SDCC_MODEL_SMALL __data modplcap_hd *aphd; /* Manejador de capa de aplicacin. */ #else modplcap_hd *aphd; /* Manejador de capa de

258

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


aplicacin. */ #endif /* Carga el manejador de capa de presentacin. */ #if defined SDCC_MODEL_SMALL aphd = (__data modplcap_hd *) param; #else aphd = (modplcap_hd *) param; #endif /* Recibe el mensaje. */ if (aphd->recvbuff) { if (!modplcap_receivemsg(aphd, aphd->recvbuff)) return; } /* Invoca a la funcin de atencin de recepcin de mensajes registrada. */ if (!aphd->recfun) return; aphd->recfun(aphd, aphd->recvbuff, aphd->param); hd; msg; }

C.2.19. Archivo modplcap_poll.c


/* modplcap_poll.c: Implementacin de la funcin modplcap_poll de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcap.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcap_poll: Verifica la llegada de un nuevo mensaje. */ #if defined SDCC_MODEL_SMALL int modplcap_poll(__data modplcap_hd *hd) #else int modplcap_poll(modplcap_hd *hd) #endif { /* Verifica que el manejador de capa de aplicacin del modem PLC exista. */ if (!hd) return 0; /* Verifica la llegada de un nuevo mensaje. */ return modplcpp_poll(hd->modpphd); }

FernandoArielBeunza79156

259

Tesis de Grado en Ingeniera Informtica

C.2.20. Archivo modplcap_status.c


/* modplcap_status.c: Implementacin de la funcin modplcap_status de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcap.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcap_status: Devuelve el estado del modem PLC. */ #if defined SDCC_MODEL_SMALL int modplcap_status(__data modplcap_hd *hd) #else int modplcap_status(modplcap_hd *hd) #endif { /* Verifica que el manejador de capa de aplicacin del modem PLC exista. */ if (!hd) return 0; /* Devuelve el estado del modem PLC. */ return modplcpp_status(hd->modpphd); }

C.2.21. Archivo modplcpp.h


/* modplcpp.h: Declaracin de funciones referentes a la capa de presentacin del modem PLC. */

#if !defined(__MODPLCPP_H__) #define __MODPLCPP_H__

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica que se encuentre definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #warning "MODPLCPP_MSGSIZE not defined" #define MODPLCPP_MSGSIZE 0 #endif #if (MODPLCPP_MSGSIZE < 1) #undef MODPLCPP_MSGSIZE

260

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


#define MODPLCPP_MSGSIZE 1 #endif #define MODPLCSP_MSGSIZE MODPLCPP_MSGSIZE

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Definicin de tipos. */ /* Identificador de grupo. */ typedef unsigned char modplcpp_grpid; /* Tipo de mensaje. */ typedef unsigned char modplcpp_mtype; /* Tipo de campo. */ typedef unsigned char modplcpp_ftype; /* Tipo mensaje. */ typedef struct { unsigned short int startoffset; unsigned short int endoffset; modplcpp_grpid grpid; modplcpp_mtype mtype; #if defined SDCC_MODEL_SMALL __data void *pphd; #else void *pphd; #endif unsigned char dat[MODPLCPP_MSGSIZE]; } modplcpp_msg; /* Manejador de capa de presentacin. */ typedef struct { short int msgsize; #if defined SDCC_MODEL_SMALL __data modplcsp_hd *modsphd; __data modplcpp_msg *recvbuff; void (*recfun) (__data void *, __data modplcpp_msg *, __data void *) __reentrant; __data void *param; /* Contenido del mensaje. */ /* Manejador de capa de presentacin. */

/* /* /* /*

Comienzo del mensaje. */ Fin del mensaje. */ Identificador de grupo. */ Tipo de mensaje. */

/* Manejador de capa de presentacin. */

/* Cantidad mxima de bytes que puede contener un mensaje. */ /* Manejador de interfaz con la capa de sesin del modem PLC. */ /* Puntero al buffer de recepcin. */

/* Funcin manejadora de mensajes recibidos. */ /* Parmetros para la funcin manejadora de mensajes recibidos. */ /* Manejador de interfaz con la capa de sesin del modem PLC. */ /* Puntero al buffer de recepcin. */

#else modplcsp_hd *modsphd; modplcpp_msg *recvbuff; void (*recfun) (void *, modplcpp_msg *, void *) __reentrant; void *param;

/* Funcin manejadora de mensajes recibidos. */ /* Parmetros para la funcin manejadora de mensajes recibidos. */

#endif } modplcpp_hd;

FernandoArielBeunza79156

261

Tesis de Grado en Ingeniera Informtica


/* Definicin de constantes. */ /* Tipo de mensaje. */ #define MODPLCPP_SECMSG #define MODPLCPP_NOSECMSG /* Tipos de datos. */ #define MODPLCPP_NULLTYPE #define MODPLCPP_CHARTYPE #define MODPLCPP_SINT8TYPE #define MODPLCPP_UINT8TYPE #define MODPLCPP_SINT16TYPE #define MODPLCPP_UINT16TYPE #define MODPLCPP_SINT32TYPE #define MODPLCPP_UINT32TYPE #define MODPLCPP_FLOATTYPE

0x00 0x01

0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08

/* Declaracin de funciones pblicas. */ /* Funcin modplcpp__init: Inicializa los recursos utilizado por la capa de presentacin del modem PLC. */ #if defined SDCC_MODEL_SMALL __data modplcpp_hd *modplcpp__init(int, short int); #else modplcpp_hd *modplcpp__init(int, short int); #endif /* Funcin modplcpp_init: Inicializa los recursos utilizado por la capa de presentacin del modem PLC. */ #define modplcpp_init(sid)\ modplcpp__init(sid, MODPLCPP_MSGSIZE) /* Funcin modplcpp_release: Libera los recursos utilizados por la capa de presentacin del modem PLC. */ #if defined SDCC_MODEL_SMALL int modplcpp_release(__data modplcpp_hd *); #else int modplcpp_release(modplcpp_hd *); #endif /* Funcin modplcpp_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ #if defined SDCC_MODEL_SMALL int modplcpp_publish(__data modplcpp_hd *, modplcpp_grpid); #else int modplcpp_publish(modplcpp_hd *, modplcpp_grpid); #endif /* Funcin modplcpp_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ #if defined SDCC_MODEL_SMALL int modplcpp_subscribe(__data modplcpp_hd *, modplcpp_grpid); #else int modplcpp_subscribe(modplcpp_hd *, modplcpp_grpid); #endif /*

262

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Funcin modplcpp_leave: Desvincula el dispositivo del grupo de difusin especificado. */ #if defined SDCC_MODEL_SMALL int modplcpp_leave(__data modplcpp_hd *, modplcpp_grpid); #else int modplcpp_leave(modplcpp_hd *, modplcpp_grpid); #endif /* Funcin modplcpp_newmsg: Crea un nuevo mensaje. */ #if defined SDCC_MODEL_SMALL int modplcpp_newmsg(__data modplcpp_hd *, __data modplcpp_msg *, modplcpp_grpid, modplcpp_mtype); #else int modplcpp_newmsg(modplcpp_hd *, modplcpp_msg *, modplcpp_grpid, modplcpp_mtype); #endif /* Funcin modplcpp_copymsg: Crea un copia de un mensaje. */ #if defined SDCC_MODEL_SMALL int modplcpp_copymsg(__data modplcpp_msg *, __data modplcpp_msg *); #else int modplcpp_copymsg(modplcpp_msg *, modplcpp_msg *); #endif /* Funcin modplcpp_putfield: Agrega un nuevo campo al mensaje. */ #if defined SDCC_MODEL_SMALL int modplcpp_putfield(__data modplcpp_msg *, modplcpp_ftype, unsigned char, const __data void *); #else int modplcpp_putfield(modplcpp_msg *, modplcpp_ftype, unsigned char, const void *); #endif /* Funcin modplcpp_sendmsg: Enva un mensaje por medio de la capa de presentacin. */ #if defined SDCC_MODEL_SMALL int modplcpp_sendmsg(__data modplcpp_msg *); #else int modplcpp_sendmsg(modplcpp_msg *); #endif /* Funcin modplcpp_receivemsg: Recibe un mensaje por medio de la capa de presentacin. */ #if defined SDCC_MODEL_SMALL int modplcpp_receivemsg(__data modplcpp_hd *, __data modplcpp_msg *); #else int modplcpp_receivemsg(modplcpp_hd *, modplcpp_msg *); #endif /* Funcin modplcpp_getfield: Extrae un campo del mensaje. */ #if defined SDCC_MODEL_SMALL int modplcpp_getfield(__data modplcpp_msg *, __data modplcpp_ftype *, __data unsigned char *, __data void *); #else

FernandoArielBeunza79156

263

Tesis de Grado en Ingeniera Informtica


int modplcpp_getfield(modplcpp_msg *, modplcpp_ftype *, unsigned char *, void *); #endif /* Funcin modplcpp_getgrpid: Devuelve el identificador de grupo del mensaje. */ #if defined SDCC_MODEL_SMALL modplcpp_grpid modplcpp_getgrpid(__data modplcpp_msg *); #else modplcpp_grpid modplcpp_getgrpid(modplcpp_msg *); #endif /* Funcin modplcpp_destroymsg: Destruye un mensaje. */ #if defined SDCC_MODEL_SMALL int modplcpp_destroymsg(__data modplcpp_msg *); #else int modplcpp_destroymsg(modplcpp_msg *); #endif /* Funcin modplcpp_setbuffer: Define el buffer de recepcin. */ #if defined SDCC_MODEL_SMALL int modplcpp_setbuffer(__data modplcpp_hd *, __data modplcpp_msg *); #else int modplcpp_setbuffer(modplcpp_hd *, modplcpp_msg *); #endif /* Funcin modplcpp_notify: Define una funcin manejadora de mensajes recibidos. */ #if defined SDCC_MODEL_SMALL int modplcpp_notify(__data modplcpp_hd *, void (*func)(__data modplcpp_hd *, __data modplcpp_msg *, __data void *), __data void *); #else int modplcpp_notify(modplcpp_hd *, void (*func)(modplcpp_hd *, modplcpp_msg *, void *), void *); #endif /* Funcin modplcpp_poll: Verifica la llegada de un nuevo mensaje. */ #if defined SDCC_MODEL_SMALL int modplcpp_poll(__data modplcpp_hd *); #else int modplcpp_poll(modplcpp_hd *); #endif /* Funcin modplcpp_status: Devuelve el estado del modem PLC. */ #if defined SDCC_MODEL_SMALL int modplcpp_status(__data modplcpp_hd *); #else int modplcpp_status(modplcpp_hd *); #endif

#endif

264

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

C.2.22. Archivo modplcpp__init.c


/* modplcpp__init.c: Implementacin de la funcin modplcpp__init de la capa de presentacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdlib.h>

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcpp.h"

/* Variables globales. */ volatile modplcpp_hd __modplcpp_hd__;

/* Implementacin de funciones pblicas. */ /* Funcin modplcpp__init: Inicializa los recursos utilizado por la capa de presentacin del modem PLC. */ #if defined SDCC_MODEL_SMALL __data modplcpp_hd *modplcpp__init(int sid, short int msgsize) #else modplcpp_hd *modplcpp__init(int sid, short int msgsize) #endif { /* Inicializa la interfaz de la capa de sesin del modem PLC. */ __modplcpp_hd__.modsphd = modplcsp__init(sid, msgsize); if (!__modplcpp_hd__.modsphd) return NULL; /* Define la cantidad mxima de bytes que puede contener un mensaje. */ __modplcpp_hd__.msgsize = msgsize; /* Inicializa el buffer de recepcin. */ __modplcpp_hd__.recvbuff = NULL; /* Inicializa la funcin manejadora de mensajes recibidos. */ __modplcpp_hd__.recfun = NULL; /* Devuelve el manejador creado. */ return &__modplcpp_hd__; }

C.2.23. Archivo modplcpp_release.c


/* modplcpp_release.c: Implementacin de la funcin modplcpp_release de la capa de presentacin del modem PLC. */

FernandoArielBeunza79156

265

Tesis de Grado en Ingeniera Informtica


/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcpp.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcpp_release: Libera los recursos utilizados por la capa de presentacin del modem PLC. */ #if defined SDCC_MODEL_SMALL int modplcpp_release(__data modplcpp_hd *hd) #else int modplcpp_release(modplcpp_hd *hd) #endif { /* Verifica que el manejador de capa de presentacin del modem PLC exista. */ if (!hd) return 0; /* Libera los recursos utilizados por la capa de sesin del modem PLC. */ return modplcsp_release(hd->modsphd); }

C.2.24. Archivo modplcpp_publish.c


/* modplcpp_publish.c: Implementacin de la funcin modplcpp_publish de la capa de presentacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcpp.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcpp_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ #if defined SDCC_MODEL_SMALL int modplcpp_publish(__data modplcpp_hd *hd, modplcpp_grpid grpid) #else int modplcpp_publish(modplcpp_hd *hd, modplcpp_grpid grpid)

266

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


#endif { /* Verifica que el manejador de capa de presentacin del modem PLC exista. */ if (!hd) return 0; /* Registra el dispositivo como publicador del grupo de difusin especificado. */ return modplcsp_publish(hd->modsphd, (modplcsp_grpid) grpid); }

C.2.25. Archivo modplcpp_subscribe.c


/* modplcpp_subscribe.c: Implementacin de la funcin modplcpp_subscribe de la capa de presentacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcpp.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcpp_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ #if defined SDCC_MODEL_SMALL int modplcpp_subscribe(__data modplcpp_hd *hd, modplcpp_grpid grpid) #else int modplcpp_subscribe(modplcpp_hd *hd, modplcpp_grpid grpid) #endif { /* Verifica que el manejador de capa de presentacin del modem PLC exista. */ if (!hd) return 0; /* Registra el dispositivo como suscriptor del grupo de difusin especificado. */ return modplcsp_subscribe(hd->modsphd, (modplcsp_grpid) grpid); }

C.2.26. Archivo modplcpp_leave.c


/* modplcpp_leave.c: Implementacin de la funcin modplcpp_leave de la capa de presentacin del modem PLC. */

/* Archivos includos necesarios. */

FernandoArielBeunza79156

267

Tesis de Grado en Ingeniera Informtica


#include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcpp.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcpp_leave: Desvincula el dispositivo del grupo de difusin especificado. */ #if defined SDCC_MODEL_SMALL int modplcpp_leave(__data modplcpp_hd *hd, modplcpp_grpid grpid) #else int modplcpp_leave(modplcpp_hd *hd, modplcpp_grpid grpid) #endif { /* Verifica que el manejador de capa de presentacin del modem PLC exista. */ if (!hd) return 0; /* Desvincula el dispositivo del grupo de difusin especificado. */ return modplcsp_leave(hd->modsphd, (modplcsp_grpid) grpid); }

C.2.27. Archivo modplcpp_newmsg.c


/* modplcpp_newmsg.c: Implementacin de la funcin modplcpp_newmsg de la capa de presentacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcpp.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcpp_newmsg: Crea un nuevo mensaje. */ #if defined SDCC_MODEL_SMALL int modplcpp_newmsg(__data modplcpp_hd *hd, __data modplcpp_msg *msg, modplcpp_grpid grpid, modplcpp_mtype mtype) #else int modplcpp_newmsg(modplcpp_hd *hd, modplcpp_msg *msg, modplcpp_grpid grpid, modplcpp_mtype mtype)

268

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


#endif { /* Verifica que el manejador de capa de presentacin del modem PLC exista. */ if (!hd) return 0; /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Inicializa el mensaje. */ msg->startoffset = 0; msg->endoffset = 0; msg->grpid = grpid; msg->mtype = mtype; msg->pphd = hd; return 1; }

C.2.28. Archivo modplcpp_copymsg.c


/* modplcpp_copymsg.c: Implementacin de la funcin modplcpp_copymsg de la capa de presentacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcpp.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcpp_copymsg: Crea un copia de un mensaje. */ #if defined SDCC_MODEL_SMALL int modplcpp_copymsg(__data modplcpp_msg *dest, __data modplcpp_msg *src) #else int modplcpp_copymsg(modplcpp_msg *dest, modplcpp_msg *src) #endif { /* Variables. */ short int i; /* Contador. */

/* Verifica que el puntero al mensaje original no sea nulo. */ if (!src) return 0; /* Verifica que el puntero a la copia del mensaje no sea nulo. */ if (!dest) return 0; /* Copia el contenido del mensaje. */ dest->startoffset = src->startoffset; dest->endoffset = src->endoffset; dest->grpid = src->grpid; dest->mtype = src->mtype;

FernandoArielBeunza79156

269

Tesis de Grado en Ingeniera Informtica


dest->pphd = src->pphd; for(i = 0; i < dest->endoffset; i++) dest->dat[i] = src->dat[i]; /* xito. */ return 1; }

C.2.29. Archivo modplcpp_putfield.c


/* modplcpp_putfield.c: Implementacin de la funcin modplcpp_putfield de la capa de presentacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcpp.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcpp_putfield: Agrega un nuevo campo al mensaje. */ #if defined SDCC_MODEL_SMALL int modplcpp_putfield(__data modplcpp_msg *msg, modplcpp_ftype type, unsigned char count, const __data void *dat) #else int modplcpp_putfield(modplcpp_msg *msg, modplcpp_ftype type, unsigned char count, const void *dat) #endif { /* Variables. */ short int msgsize; /* Tamao del mensaje. */ #if defined SDCC_MODEL_SMALL __data unsigned char *ptr; /* Puntero a los datos. */ #else unsigned char *ptr; /* Puntero a los datos. */ #endif

/* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Inicializa el puntero a los datos. */ #if defined SDCC_MODEL_SMALL ptr = (__data unsigned char *) dat; #else ptr = (unsigned char *) dat; #endif /* Verifica si el nuevo campo puede entrar en el mensaje. */ msgsize = msg->endoffset; msgsize += sizeof(modplcpp_ftype); msgsize += sizeof(unsigned char); if ((type == MODPLCPP_CHARTYPE) || (type == MODPLCPP_UINT8TYPE))

270

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


msgsize += count * sizeof(unsigned char); else if (type == MODPLCPP_SINT8TYPE) msgsize += count * sizeof(char); else if ((type == MODPLCPP_SINT16TYPE) || (type == MODPLCPP_UINT16TYPE)) msgsize += count * sizeof(unsigned short int); else if ((type == MODPLCPP_SINT32TYPE) || (type == MODPLCPP_UINT32TYPE)) msgsize += count * sizeof(unsigned long int); else if (type == MODPLCPP_FLOATTYPE) msgsize += count * sizeof(float); else return 0; if (msgsize > modplcsp_getpayloadsize(((modplcpp_hd *) (msg->pphd))->modsphd)) return 0; /* Agrega el tipo de dato. */ *(msg->dat + msg->endoffset) = type; msg->endoffset += sizeof(modplcpp_ftype); /* Agrega la cantidad de datos. */ *(msg->dat + msg->endoffset) = count; msg->endoffset += sizeof(unsigned char); /* Agrega datos tipo caracter o entero de 8 bits sin signo. */ if ((type == MODPLCPP_CHARTYPE) || (type == MODPLCPP_UINT8TYPE)) { while(count--) { *(msg->dat + msg->endoffset) = *ptr; ptr += sizeof(unsigned char); msg->endoffset += sizeof(unsigned char); } } /* Agrega datos tipo entero de 8 bits con signo. */ else if (type == MODPLCPP_SINT8TYPE) { while(count--) { *(msg->dat + msg->endoffset) = *ptr; ptr += sizeof(char); msg->endoffset += sizeof(char); } } /* Agrega datos tipo entero de 16 bits. */ else if ((type == MODPLCPP_SINT16TYPE) || (type == MODPLCPP_UINT16TYPE)) { while(count--) { *(msg->dat + msg->endoffset + 0) = *(ptr + 1); *(msg->dat + msg->endoffset + 1) = *(ptr + 0); ptr += sizeof(unsigned short int); msg->endoffset += sizeof(unsigned short int); } } /* Agrega datos tipo entero de 32 bits. */ else if ((type == MODPLCPP_SINT32TYPE) || (type == MODPLCPP_UINT32TYPE)) { while(count--) { *(msg->dat + msg->endoffset + 0) = *(ptr + 3); *(msg->dat + msg->endoffset + 1) = *(ptr + 2); *(msg->dat + msg->endoffset + 2) = *(ptr + 1); *(msg->dat + msg->endoffset + 3) = *(ptr + 0); ptr += sizeof(unsigned long int); msg->endoffset += sizeof(unsigned long int); } } /* Agrega datos tipo punto flotante. */ else if (type == MODPLCPP_FLOATTYPE) { while(count--)

FernandoArielBeunza79156

271

Tesis de Grado en Ingeniera Informtica


{ *(msg->dat + msg->endoffset) = *ptr; ptr += sizeof(float); msg->endoffset += sizeof(float); } } /* xito. */ return 1; }

C.2.30. Archivo modplcpp_sendmsg.c


/* modplcpp_sendmsg.c: Implementacin de la funcin modplcpp_sendmsg de la capa de presentacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcpp.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcpp_sendmsg: Enva un mensaje por medio de la capa de presentacin. */ #if defined SDCC_MODEL_SMALL int modplcpp_sendmsg(__data modplcpp_msg *msg) #else int modplcpp_sendmsg(modplcpp_msg *msg) #endif { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Enva un mensaje. */ if (modplcsp_send(((modplcpp_hd *) (msg->pphd))->modsphd, msg->grpid, msg->mtype, msg->dat, msg->endoffset) == msg->endoffset) return 1; return 0; }

C.2.31. Archivo modplcpp_receivemsg.c


/* modplcpp_receivemsg.c: Implementacin de la funcin modplcpp_receivemsg de la capa de presentacin del modem PLC. */

272

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcpp.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcpp_receivemsg: Recibe un mensaje por medio de la capa de presentacin. */ #if defined SDCC_MODEL_SMALL int modplcpp_receivemsg(__data modplcpp_hd *hd, __data modplcpp_msg *msg) #else int modplcpp_receivemsg(modplcpp_hd *hd, modplcpp_msg *msg) #endif { /* Verifica el estado del modem PLC. */ if (!modplcpp_status(hd)) return 0; /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Espera la llegada de un mensaje. */ while(!modplcpp_poll(hd)); /* Recibe el mensaje. */ msg->startoffset = 0; msg->endoffset = modplcsp_receive(hd->modsphd, &(msg->grpid), msg->dat, hd->msgsize); return (msg->endoffset != 0); }

C.2.32. Archivo modplcpp_getfield.c


/* modplcpp_getfield.c: Implementacin de la funcin modplcpp_getfield de la capa de presentacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcpp.h"

/* Implementacin de funciones pblicas. */ /*

FernandoArielBeunza79156

273

Tesis de Grado en Ingeniera Informtica


Funcin modplcpp_getfield: Extrae un campo del mensaje. */ #if defined SDCC_MODEL_SMALL int modplcpp_getfield(__data modplcpp_msg *msg, __data modplcpp_ftype *type, __data unsigned char *count, __data void *dat) #else int modplcpp_getfield(modplcpp_msg *msg, modplcpp_ftype *type, unsigned char *count, void *dat) #endif { /* Variables. */ unsigned char c; /* Contador. */ #if defined SDCC_MODEL_SMALL __data unsigned char *ptr; /* Puntero a los datos. */ #else unsigned char *ptr; /* Puntero a los datos. */ #endif

/* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Inicializa el puntero a los datos. */ #if defined SDCC_MODEL_SMALL ptr = (__data unsigned char *) dat; #else ptr = (unsigned char *) dat; #endif /* Extrae el tipo de dato. */ *type = *(msg->dat + msg->startoffset); msg->startoffset += sizeof(modplcpp_ftype); /* Extrae la cantidad de datos. */ c = *(msg->dat + msg->startoffset); *count = c; msg->startoffset += sizeof(unsigned char); /* Agrega datos tipo caracter o entero de 8 bits. */ if ((*type == MODPLCPP_CHARTYPE) || (*type == MODPLCPP_SINT8TYPE) || (*type == MODPLCPP_UINT8TYPE)) { while(c --) { *ptr = *(msg->dat + msg->startoffset); ptr += sizeof(unsigned char); msg->startoffset += sizeof(unsigned char); } return 1; } /* Agrega datos tipo entero de 16 bits. */ if ((*type == MODPLCPP_SINT16TYPE) || (*type == MODPLCPP_UINT16TYPE)) { while(c --) { *(ptr + 1) = *(msg->dat + msg->startoffset + 0); *(ptr + 0) = *(msg->dat + msg->startoffset + 1); ptr += sizeof(unsigned short int); msg->startoffset += sizeof(unsigned short int); } return 1; } /* Agrega datos tipo entero de 32 bits. */ if ((*type == MODPLCPP_SINT32TYPE) || (*type == MODPLCPP_UINT32TYPE)) { while(c --) { *(ptr + 3) = *(msg->dat + msg->startoffset + 0);

274

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


*(ptr + 2) = *(msg->dat + msg->startoffset + 1); *(ptr + 1) = *(msg->dat + msg->startoffset + 2); *(ptr + 0) = *(msg->dat + msg->startoffset + 3); ptr += sizeof(unsigned long int); msg->startoffset += sizeof(unsigned long int); } return 1; } /* Agrega datos tipo punto flotante. */ if (*type == MODPLCPP_FLOATTYPE) { while(c --) { *ptr = *(msg->dat + msg->startoffset); ptr += sizeof(float); msg->startoffset += sizeof(float); } return 1; } /* Tipo de dato desconocido. */ msg->startoffset -= sizeof(unsigned char); msg->startoffset -= sizeof(modplcpp_ftype); return 0; }

C.2.33. Archivo modplcpp_getgrpid.c


/* modplcpp_getgrpid.c: Implementacin de la funcin modplcpp_getgrpid de la capa de presentacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcpp.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcpp_getgrpid: Devuelve el identificador de grupo del mensaje. */ #if defined SDCC_MODEL_SMALL modplcpp_grpid modplcpp_getgrpid(__data modplcpp_msg *msg) #else modplcpp_grpid modplcpp_getgrpid(modplcpp_msg *msg) #endif { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Devuelve el identificador de grupo del mensaje. */ return msg->grpid; }

FernandoArielBeunza79156

275

Tesis de Grado en Ingeniera Informtica

C.2.34. Archivo modplcpp_destroymsg.c


/* modplcpp_destroymsg.c: Implementacin de la funcin modplcpp_destroymsg de la capa de presentacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdlib.h>

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcpp.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcpp_destroymsg: Destruye un mensaje. */ #if defined SDCC_MODEL_SMALL int modplcpp_destroymsg(__data modplcpp_msg *msg) #else int modplcpp_destroymsg(modplcpp_msg *msg) #endif { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Destruye el mensaje. */ msg->startoffset = 0; msg->endoffset = 0; msg->grpid = 0; msg->mtype = 0; msg->pphd = NULL; return 1; }

C.2.35. Archivo modplcpp_setbuffer.c


/* modplcpp_setbuffer.c: Implementacin de la funcin modplcsp_setbuffer de la capa de presentacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif

276

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Archivos includos necesarios. */ #include "modplcpp.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcpp_setbuffer: Define el buffer de recepcin. */ #if defined SDCC_MODEL_SMALL int modplcpp_setbuffer(__data modplcpp_hd *hd, __data modplcpp_msg *buffer) #else int modplcpp_setbuffer(modplcpp_hd *hd, modplcpp_msg *buffer) #endif { /* Verifica el estado del modem PLC. */ if (!modplcpp_status(hd)) return 0; /* Define el buffer de recepcin. */ hd->recvbuff = buffer; return 1; }

C.2.36. Archivo modplcpp_notify.c


/* modplcpp_notify.c: Implementacin de la funcin modplcpp_notify de la capa de presentacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdlib.h>

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcpp.h"

/* Declaracin de funciones privadas. */ #if defined SDCC_MODEL_SMALL static void __modplcpp_procmsg__(__data modplcsp_hd *, modplcsp_grpid, __data void *, short int, __data void *) __reentrant; #else static void __modplcpp_procmsg__(modplcsp_hd *, modplcsp_grpid, void *, short int, void *) __reentrant; #endif

/* Implementacin de funciones pblicas. */ /* Funcin modplcpp_notify: Define una funcin manejadora de mensajes recibidos. */ #if defined SDCC_MODEL_SMALL int modplcpp_notify(__data modplcpp_hd *hd, void (*func)(__data modplcpp_hd *,

FernandoArielBeunza79156

277

Tesis de Grado en Ingeniera Informtica


__data modplcpp_msg *, __data void *), __data void *param) #else int modplcpp_notify(modplcpp_hd *hd, void (*func)(modplcpp_hd *, modplcpp_msg *, void *), void *param) #endif { /* Verifica que el manejador de capa de presentacin del modem PLC exista. */ if (!hd) return 0; /* Define un manejador de mensajes recibidos. */ #if defined SDCC_MODEL_SMALL hd->recfun = (void (*)(__data void *, __data modplcpp_msg *, __data void *)) func; #else hd->recfun = (void (*)(void *, modplcpp_msg *, void *)) func; #endif if (!modplcsp_notify(hd->modsphd, __modplcpp_procmsg__, hd)) { hd->recfun = NULL; return 0; } hd->param = param; return 1; }

/* Implementacin de funciones privadas. */ /* Funcin __modplcpp_procmsg__: Procesa un mensaje recibido por medio de la capa de sesin. */ #if defined SDCC_MODEL_SMALL static void __modplcpp_procmsg__(__data modplcsp_hd *hd, modplcsp_grpid grpid, __data void *msg, short int msgsize, __data void *param) __reentrant #else static void __modplcpp_procmsg__(modplcsp_hd *hd, modplcsp_grpid grpid, void *msg, short int msgsize, void *param) __reentrant #endif { /* Variables. */ #if defined SDCC_MODEL_SMALL __data modplcpp_hd *pphd; /* Manejador de capa de presentacin. */ #else modplcpp_hd *pphd; /* Manejador de capa de presentacin. */ #endif /* Carga el manejador de capa de presentacin. */ #if defined SDCC_MODEL_SMALL pphd = (__data modplcpp_hd *) param; #else pphd = (modplcpp_hd *) param; #endif /* Recibe el mensaje. */ if (pphd->recvbuff) { if (!modplcpp_receivemsg(pphd, pphd->recvbuff)) return; } /* Invoca a la funcin de atencin de recepcin de mensajes registrada. */ if (!pphd->recfun) return; pphd->recfun(pphd, pphd->recvbuff, pphd->param); modplcpp_destroymsg(pphd->recvbuff); hd; grpid;

278

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


msg; msgsize; }

C.2.37. Archivo modplcpp_poll.c


/* modplcpp_poll.c: Implementacin de la funcin modplcpp_poll de la capa de presentacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcpp.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcpp_poll: Verifica la llegada de un nuevo mensaje. */ #if defined SDCC_MODEL_SMALL int modplcpp_poll(__data modplcpp_hd *hd) #else int modplcpp_poll(modplcpp_hd *hd) #endif { /* Verifica que el manejador de capa de presentacin del modem PLC exista. */ if (!hd) return 0; /* Verifica la llegada de un nuevo mensaje. */ return modplcsp_poll(hd->modsphd); }

C.2.38. Archivo modplcpp_status.c


/* modplcpp_status.c: Implementacin de la funcin modplcpp_status de la capa de presentacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif

FernandoArielBeunza79156

279

Tesis de Grado en Ingeniera Informtica


/* Archivos includos necesarios. */ #include "modplcpp.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcpp_status: Devuelve el estado del modem PLC. */ #if defined SDCC_MODEL_SMALL int modplcpp_status(__data modplcpp_hd *hd) #else int modplcpp_status(modplcpp_hd *hd) #endif { /* Verifica que el manejador de capa de presentacin del modem PLC exista. */ if (!hd) return 0; /* Devuelve el estado del modem PLC. */ return modplcsp_status(hd->modsphd); }

C.2.39. Archivo modplcsp.h


/* modplcsp.h: Declaracin de funciones referentes a la interfaz de la capa de sesin del modem PLC. */

#if !defined(__MODPLCSP_H__) #define __MODPLCSP_H__

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica que se encuentre definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #warning "MODPLCSP_MSGSIZE not defined" #define MODPLCSP_MSGSIZE 0 #endif

/* Definicin de tipos. */ /* Identificador de grupo. */ typedef unsigned char modplcsp_grpid; /* Manejador de interfaz con la capa de sesin del modem PLC. */ typedef struct { int status; /* Estado del modem PLC. */ short int msgsize; /* Cantidad mxima de bytes que puede contener un mensaje. */ short int buffsize; /* Tamao del buffer de recepcin. */ short int polltimer; /* Temporizador de verificacin de recepcin de mensaje. */ short int payloadsize; /* Cantidad mxima de bytes que puede contener un mensaje. */ #if defined SDCC_MODEL_SMALL __data unsigned char *recvbuff; /* Puntero al buffer de

280

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


recepcin. */ void (*recfun) (__data void *, modplcsp_grpid, __data void *, short int, __data void *) __reentrant; __data void *param;

/* Funcin manejadora de mensajes recibidos. */ /* Parmetros para la funcin manejadora de mensajes recibidos. */ /* Puntero al buffer de recepcin. */

#else unsigned char *recvbuff; void (*recfun) (void *, modplcsp_grpid, void *, short int, void *) __reentrant; void *param;

/* Funcin manejadora de mensajes recibidos. */ /* Parmetros para la funcin manejadora de mensajes recibidos. */

#endif } modplcsp_hd;

/* Declaracin de funciones pblicas. */ /* Funcin modplcsp__init: Inicializa los recursos utilizados por la capa de sesin del modem PLC. */ #if defined SDCC_MODEL_SMALL __data modplcsp_hd *modplcsp__init(int, short int); #else modplcsp_hd *modplcsp__init(int, short int); #endif /* Funcin modplcsp_init: Inicializa los recursos utilizados por la capa de sesin del modem PLC. */ #define modplcsp_init(sid)\ modplcsp__init(sid, MODPLCSP_MSGSIZE) /* Funcin modplcsp_release: Libera los recursos utilizados por la capa de sesin del modem PLC. */ #if defined SDCC_MODEL_SMALL int modplcsp_release(__data modplcsp_hd *); #else int modplcsp_release(modplcsp_hd *); #endif /* Funcin modplcsp_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ #if defined SDCC_MODEL_SMALL int modplcsp_publish(__data modplcsp_hd *, modplcsp_grpid); #else int modplcsp_publish(modplcsp_hd *, modplcsp_grpid); #endif /* Funcin modplcsp_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ #if defined SDCC_MODEL_SMALL int modplcsp_subscribe(__data modplcsp_hd *, modplcsp_grpid); #else int modplcsp_subscribe(modplcsp_hd *, modplcsp_grpid); #endif

FernandoArielBeunza79156

281

Tesis de Grado en Ingeniera Informtica


/* Funcin modplcsp_leave: Desvincula el dispositivo del grupo de difusin especificado. */ #if defined SDCC_MODEL_SMALL int modplcsp_leave(__data modplcsp_hd *, modplcsp_grpid); #else int modplcsp_leave(modplcsp_hd *, modplcsp_grpid); #endif /* Funcin modplcsp_send: Enva un mensaje por medio de la capa de sesin del modem PLC. */ #if defined SDCC_MODEL_SMALL short int modplcsp_send(__data modplcsp_hd *, modplcsp_grpid, unsigned char, const __data void *, short int); #else short int modplcsp_send(modplcsp_hd *, modplcsp_grpid, unsigned char, const void *, short int); #endif /* Funcin modplcsp_receive: Recibe un mensaje por medio de la capa de sesin del modem PLC. */ #if defined SDCC_MODEL_SMALL short int modplcsp_receive(__data modplcsp_hd *, __data modplcsp_grpid *, __data void *, short int); #else short int modplcsp_receive(modplcsp_hd *, modplcsp_grpid *, void *, short int); #endif /* Funcin modplcsp_setbuffer: Define el buffer de recepcin. */ #if defined SDCC_MODEL_SMALL int modplcsp_setbuffer(__data modplcsp_hd *, __data void *, short int); #else int modplcsp_setbuffer(modplcsp_hd *, void *, short int); #endif /* Funcin modplcsp_notify: Define una funcin manejadora de mensajes recibidos. */ #if defined SDCC_MODEL_SMALL int modplcsp_notify(__data modplcsp_hd *, void (*func)(__data modplcsp_hd *, modplcsp_grpid, __data void *, short int, __data void *), __data void *); #else int modplcsp_notify(modplcsp_hd *, void (*func)(modplcsp_hd *, modplcsp_grpid, void *, short int, void *), void *); #endif /* Funcin modplcsp_poll: Verifica la llegada de un nuevo mensaje. */ #if defined SDCC_MODEL_SMALL int modplcsp_poll(__data modplcsp_hd *); #else int modplcsp_poll(modplcsp_hd *); #endif /* Funcin modplcsp_status: Devuelve el estado del modem PLC. */

282

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


#if defined SDCC_MODEL_SMALL int modplcsp_status(__data modplcsp_hd *); #else int modplcsp_status(modplcsp_hd *); #endif /* Funcin modplcsp_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de sesin del modem PLC. */ #if defined SDCC_MODEL_SMALL short int modplcsp_getpayloadsize(__data modplcsp_hd *); #else short int modplcsp_getpayloadsize(modplcsp_hd *); #endif /* Interrupcin INT1: Procesa el mensaje recibido. */ extern void __modplcsp_int1__(void) __interrupt 1;

#endif

C.2.40. Archivo modplcsp__init.c


/* modplcsp__init.c: Implementacin de la funcin modplcsp__init de la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdlib.h> #include "serial.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Definicin de SFR necesarias. */ __sfr __at (0x8a) SIO_TL0; __sfr __at (0x8c) SIO_TH0; __sbit __at (0x8c) SIO_TR0;

/* Variables globales. */ volatile modplcsp_hd __modplcsp_hd__;

/* Declaracin de funciones privadas. */ void __modplcsp_waitchar__(char); short int __modplcsp_sendcmd0__(modplcsp_hd *, char);

/* Implementacin de funciones pblicas. */

FernandoArielBeunza79156

283

Tesis de Grado en Ingeniera Informtica


/* Funcin modplcsp__init: Inicializa los recursos utilizados por la capa de sesin del modem PLC. */ #if defined SDCC_MODEL_SMALL __data modplcsp_hd *modplcsp__init(int sid, short int msgsize) #else modplcsp_hd *modplcsp__init(int sid, short int msgsize) #endif { /* Variables. */ char c; /* Caracter recibido. */

/* Verifica la validez del identificador de interface fsica. */ if (sid != 1) return NULL; /* Inicializa la interfaz fsica. */ inituart(0xff); /* Solicita acceder a la capa de sesin del modem PLC. */ c = 0; while(1) { if (!c) putchar('\n'); c = getchar(); if (c == MODPLC_INITPROMPT) { putchar('i'); putchar('n'); putchar('i'); putchar('t'); } else if ((c == MODPLC_LAYPROMPT) || (c == MODPLC_NORMPROMPT)) putchar(MODPLC_NORMRESET); else if (c == MODPLC_PARAMPROMPT) putchar(MODPLC_PARAMRESET); else continue; putchar('\n'); break; } __modplcsp_waitchar__(MODPLC_LAYPROMPT); putchar(MODPLC_SESSIONLAYER); putchar('\n'); __modplcsp_waitchar__(MODPLC_NORMPROMPT); /* Inicializa el buffer de recepcin. */ __modplcsp_hd__.buffsize = 0; __modplcsp_hd__.recvbuff = NULL; /* Define la cantidad mxima de bytes que puede contener un mensaje. */ __modplcsp_hd__.msgsize = msgsize; /* Inicializa el estado del modem PLC. */ __modplcsp_hd__.status = 1; /* Inicializa la funcin manejadora de mensajes recibidos. */ __modplcsp_hd__.recfun = NULL; /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ __modplcsp_hd__.payloadsize = __modplcsp_sendcmd0__(&__modplcsp_hd__, MODPLCSP_GETPAYLOADSIZE); if (!__modplcsp_hd__.payloadsize) return NULL; /* Devuelve el manejador creado. */ return &__modplcsp_hd__; }

/* Implementacin de funciones privadas. */

284

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Interrupcin INT1: Procesa el mensaje recibido. */ void __modplcsp_int1__(void) __interrupt 1 { /* Variables. */ short int msgsize; modplcsp_grpid grpid;

/* Tamao del mensaje. */ /* Identificador de grupo. */

/* Desactiva las interrupciones. */ __asm clr EA __endasm; /* Verifica la recepcin de un mensaje y lo procesa. */ SIO_TR0 = 0; while(1) { /* Verifica si transcurri el intervalo de espera. */ if (__modplcsp_hd__.polltimer < MODPLCSP_POLLINTERVAL) { __modplcsp_hd__.polltimer ++; break; } __modplcsp_hd__.polltimer = 0; /* Verifica la recepcin de un nuevo mensaje. */ if (!modplcsp_poll(&__modplcsp_hd__)) break; /* Recibe el mensaje. */ grpid = 0; msgsize = 0; if (__modplcsp_hd__.recvbuff && __modplcsp_hd__.buffsize) { msgsize = modplcsp_receive(&__modplcsp_hd__, &grpid, __modplcsp_hd__.recvbuff, __modplcsp_hd__.buffsize); if (!msgsize) break; } /* Invoca a la funcin manejadora de mensajes recibidos. */ if (!__modplcsp_hd__.recfun) break; __modplcsp_hd__.recfun(&__modplcsp_hd__, grpid, __modplcsp_hd__.recvbuff, msgsize, __modplcsp_hd__.param); } SIO_TH0 = 0xfc; SIO_TL0 = 0x66; SIO_TR0 = 1; /* Activa las interrupciones. */ __asm setb EA __endasm; }

C.2.41. Archivo modplcsp_release.c


/* modplcsp_release.c: Implementacin de la funcin modplcsp_release de la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

FernandoArielBeunza79156

285

Tesis de Grado en Ingeniera Informtica


/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcsp_release: Libera los recursos utilizados por la capa de sesin del modem PLC. */ #if defined SDCC_MODEL_SMALL int modplcsp_release(__data modplcsp_hd *hd) #else int modplcsp_release(modplcsp_hd *hd) #endif { /* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* xito. */ return 1; }

C.2.42. Archivo modplcsp_publish.c


/* modplcsp_publish.c: Implementacin de la funcin modplcsp_publish de la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Declaracin de funciones privadas. */ #if defined SDCC_MODEL_SMALL short int __modplcsp_sendcmd1__(__data modplcsp_hd *, char, unsigned char); #else short int __modplcsp_sendcmd1__(modplcsp_hd *, char, unsigned char); #endif

/* Implementacin de funciones pblicas. */ /* Funcin modplcsp_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ #if defined SDCC_MODEL_SMALL

286

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


int modplcsp_publish(__data modplcsp_hd *hd, modplcsp_grpid grpid) #else int modplcsp_publish(modplcsp_hd *hd, modplcsp_grpid grpid) #endif { return (__modplcsp_sendcmd1__(hd, MODPLCSP_PUBLISH, grpid) != 0); }

C.2.43. Archivo modplcsp_subscribe.c


/* modplcsp_subscribe.c: Implementacin de la funcin modplcsp_subscribe de la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Declaracin de funciones privadas. */ #if defined SDCC_MODEL_SMALL short int __modplcsp_sendcmd1__(__data modplcsp_hd *, char, unsigned char); #else short int __modplcsp_sendcmd1__(modplcsp_hd *, char, unsigned char); #endif

/* Implementacin de funciones pblicas. */ /* Funcin modplcsp_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ #if defined SDCC_MODEL_SMALL int modplcsp_subscribe(__data modplcsp_hd *hd, modplcsp_grpid grpid) #else int modplcsp_subscribe(modplcsp_hd *hd, modplcsp_grpid grpid) #endif { return (__modplcsp_sendcmd1__(hd, MODPLCSP_SUBSCRIBE, grpid) != 0); }

C.2.44. Archivo modplcsp_leave.c


/* modplcsp_leave.c: Implementacin de la funcin modplcsp_leave de la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

FernandoArielBeunza79156

287

Tesis de Grado en Ingeniera Informtica

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Declaracin de funciones privadas. */ #if defined SDCC_MODEL_SMALL short int __modplcsp_sendcmd1__(__data modplcsp_hd *, char, unsigned char); #else short int __modplcsp_sendcmd1__(modplcsp_hd *, char, unsigned char); #endif

/* Implementacin de funciones pblicas. */ /* Funcin modplcsp_leave: Desvincula el dispositivo del grupo de difusin especificado. */ #if defined SDCC_MODEL_SMALL int modplcsp_leave(__data modplcsp_hd *hd, modplcsp_grpid grpid) #else int modplcsp_leave(modplcsp_hd *hd, modplcsp_grpid grpid) #endif { return (__modplcsp_sendcmd1__(hd, MODPLCSP_LEAVE, grpid) != 0); }

C.2.45. Archivo modplcsp_send.c


/* modplcsp_send.c: Implementacin de la funcin modplcsp_send de la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include "serial.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Declaracin de funciones privadas. */ void __modplcsp_putcmd__(char); void __modplcsp_waitchar__(char); void __modplcsp_putint__(short int); short int __modplcsp_getbyte__(void); void __modplcsp_puthex__(unsigned char); void __modplcsp_putbyte__(unsigned char); #if defined SDCC_MODEL_SMALL short int __modplcsp_getresult__(__data modplcsp_hd *);

288

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


#else short int __modplcsp_getresult__(modplcsp_hd *); #endif

/* Implementacin de funciones pblicas. */ /* Funcin modplcsp_send: Enva un mensaje por medio de la capa de sesin del modem PLC. */ #if defined SDCC_MODEL_SMALL short int modplcsp_send(__data modplcsp_hd *hd, modplcsp_grpid grpid, unsigned char nosec, const __data void *msg, short int msgsize) #else short int modplcsp_send(modplcsp_hd *hd, modplcsp_grpid grpid, unsigned char nosec, const void *msg, short int msgsize) #endif { /* Variables. */ int i; /* Contador. */ char c; /* Caracter recibido. */ #if defined SDCC_MODEL_SMALL __data unsigned char *ptr; /* Puntero al mensaje. */ #else unsigned char *ptr; /* Puntero al mensaje. */ #endif /* Verifica el estado del modem PLC. */ if (!modplcsp_status(hd)) return 0; /* Enva un mensaje. */ __modplcsp_putcmd__(MODPLCSP_SEND); __modplcsp_putbyte__(grpid); __modplcsp_putbyte__(nosec); __modplcsp_putint__(msgsize); __modplcsp_waitchar__('\n'); i = 0; #if defined SDCC_MODEL_SMALL ptr = (__data unsigned char *) msg; #else ptr = (unsigned char *) msg; #endif while(msgsize) { if (i >= 32) { putchar('\n'); i = 0; } while(!i) { c = getchar(); if (c == '>') break; } c = *ptr; if ((c >= 0x20) && (c <= 0x7e) && (c != '\\') && (c != MODPLC_INITPROMPT) && (c != MODPLC_LAYPROMPT) && (c != MODPLC_NORMPROMPT) && (c != MODPLC_PARAMPROMPT)) putchar(*ptr); else __modplcsp_puthex__(*ptr); msgsize --; ptr ++; i ++; } if (i) putchar('\n'); /* Devuelve la cantidad de bytes envados. */

FernandoArielBeunza79156

289

Tesis de Grado en Ingeniera Informtica


return __modplcsp_getresult__(hd); }

C.2.46. Archivo modplcsp_receive.c


/* modplcsp_receive.c: Implementacin de la funcin modplcsp_receive de la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include "serial.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Declaracin de funciones privadas. */ void __modplcsp_putcmd__(char); void __modplcsp_waitchar__(char); void __modplcsp_putint__(short int); short int __modplcsp_getbyte__(void); short int __modplcsp_getresult__(void);

/* Implementacin de funciones pblicas. */ /* Funcin modplcsp_receive: Recibe un mensaje por medio de la capa de sesin del modem PLC. */ #if defined SDCC_MODEL_SMALL short int modplcsp_receive(__data modplcsp_hd *hd, __data modplcsp_grpid *grpid, __data void *msg, short int msgsize) #else short int modplcsp_receive(modplcsp_hd *hd, modplcsp_grpid *grpid, void *msg, short int msgsize) #endif { /* Variables. */ short int recvbyte; /* Byte recibido. */ short int received; /* Cantidad de bytes recibido. */ unsigned char i; /* Contador. */ #if defined SDCC_MODEL_SMALL __data unsigned char *ptr; /* Puntero al mensaje. */ #else unsigned char *ptr; /* Puntero al mensaje. */ #endif

/* Verifica el estado del modem PLC. */ if (!modplcsp_status(hd)) return 0; /* Solicita el mensaje recibido. */ __modplcsp_putcmd__(MODPLCSP_RECEIVE); __modplcsp_putint__(0x7fff); __modplcsp_waitchar__('\n');

290

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Recibe el identificador de grupo asociado al mensaje. */ *grpid = __modplcsp_getbyte__() & 0x00ff; __modplcsp_waitchar__('\n'); /* Recibe la cantidad de bytes del mensaje. */ msgsize = __modplcsp_getresult__(); /* Recibe el mensaje. */ received = 0; #if defined SDCC_MODEL_SMALL ptr = (__data unsigned char *) msg; #else ptr = (unsigned char *) msg; #endif while(1) { recvbyte = __modplcsp_getbyte__(); if (recvbyte & 0xff00) break; else if ((msgsize) && (received <= hd->msgsize)) { *ptr = recvbyte & 0x00ff; received ++; msgsize --; ptr ++; } } /* Verifica el estado del modem PLC. */ if (((char) (recvbyte >> 8)) == MODPLC_INITPROMPT) { received = 0; hd->status = 0; } /* Verifica si el mensaje recibido super el tamao permitido. */ if (received > hd->msgsize) { received = 0; hd->status = 0; do { putchar('0'); for(i = 0; i < 10; i++) putchar('\n'); } while(__modplcsp_getbyte__() != (MODPLC_INITPROMPT << 8)); } /* Devuelve la cantidad de bytes recibidos. */ return received; }

C.2.47. Archivo modplcsp_setbuffer.c


/* modplcsp_setbuffer.c: Implementacin de la funcin modplcsp_setbuffer de la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include "serial.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE)

FernandoArielBeunza79156

291

Tesis de Grado en Ingeniera Informtica


#define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcsp_setbuffer: Define el buffer de recepcin. */ #if defined SDCC_MODEL_SMALL int modplcsp_setbuffer(__data modplcsp_hd *hd, __data void *buffer, short int size) #else int modplcsp_setbuffer(modplcsp_hd *hd, void *buffer, short int size) #endif { /* Verifica el estado del modem PLC. */ if (!modplcsp_status(hd)) return 0; /* Define el buffer de recepcin. */ hd->buffsize = size; hd->recvbuff = buffer; return 1; }

C.2.48. Archivo modplcsp_notify.c


/* modplcsp_notify.c: Implementacin de la funcin modplcsp_notify de la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Definicin de SFR necesarias. */ __sfr __at (0x89) SIO_TMOD; __sfr __at (0x8a) SIO_TL0; __sfr __at (0x8c) SIO_TH0; __sfr __at (0xa8) SIO_IE; __sbit __at (0x8c) SIO_TR0; __sbit __at (0x8d) SIO_TF0;

/* Implementacin de funciones pblicas. */ /* Funcin modplcsp_notify: Define una funcin manejadora de mensajes recibidos. */ #if defined SDCC_MODEL_SMALL

292

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


int modplcsp_notify(__data modplcsp_hd *hd, void (*func)(__data modplcsp_hd *, modplcsp_grpid, __data void *, short int, __data void *), __data void *param) #else int modplcsp_notify(modplcsp_hd *hd, void (*func)(modplcsp_hd *, modplcsp_grpid, void *, short int, void *), void *param) #endif { /* Verifica el estado del modem PLC. */ if (!modplcsp_status(hd)) return 0; /* Define una funcin manejadora de mensajes recibidos.*/ #if defined SDCC_MODEL_SMALL hd->recfun = (void (*)(__data void *, modplcsp_grpid, __data void *, short int, __data void *)) func; #else hd->recfun = (void (*)(void *, modplcsp_grpid, void *, short int, void *)) func; #endif hd->param = param; /* Activa la verificacin de recepcin de mensajes. */ SIO_IE &= 0xfd; if (hd->recfun) { hd->polltimer = 0; SIO_TMOD = (SIO_TMOD & 0xf0) | 0x01; SIO_TH0 = 0xfc; SIO_TL0 = 0x66; SIO_TR0 = 1; SIO_IE |= 0x82; } else { SIO_TMOD &= 0xfd; SIO_TR0 = 0; } /* xito. */ return 1; }

C.2.49. Archivo modplcsp_poll.c


/* modplcsp_poll.c: Implementacin de la funcin modplcsp_poll de la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Declaracin de funciones privadas. */ #if defined SDCC_MODEL_SMALL short int __modplcsp_sendcmd0__(__data modplcsp_hd *, char);

FernandoArielBeunza79156

293

Tesis de Grado en Ingeniera Informtica


#else short int __modplcsp_sendcmd0__(modplcsp_hd *, char); #endif

/* Implementacin de funciones pblicas. */ /* Funcin modplcsp_poll: Verifica la llegada de un nuevo mensaje. */ #if defined SDCC_MODEL_SMALL int modplcsp_poll(__data modplcsp_hd *hd) #else int modplcsp_poll(modplcsp_hd *hd) #endif { return (__modplcsp_sendcmd0__(hd, MODPLCSP_POLL) != 0); }

C.2.50. Archivo modplcsp_status.c


/* modplcsp_status.c: Implementacin de la funcin modplcsp_status de la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include "serial.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Declaracin de funciones privadas. */ void __modplcsp_waitchar__(char);

/* Implementacin de funciones pblicas. */ /* Funcin modplcsp_status: Devuelve el estado del modem PLC. */ #if defined SDCC_MODEL_SMALL int modplcsp_status(__data modplcsp_hd *hd) #else int modplcsp_status(modplcsp_hd *hd) #endif { /* Variables. */ char c;

/* Caracter recibido. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0;

294

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Verifica el estado del modem PLC. */ if (!hd->status) return 0; putchar('\n'); while(1) { c = getchar(); if (c == MODPLC_NORMPROMPT) break; else if (c == MODPLC_INITPROMPT) { hd->status = 0; break; } } return hd->status; }

C.2.51. Archivo modplcsp_getpayloadsize.c


/* modplcsp_getpayloadsize.c: Implementacin de la funcin modplcsp_getpayloadsize de la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Implementacin de funciones pblicas. */ /* Funcin modplcsp_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de sesin del modem PLC. */ #if defined SDCC_MODEL_SMALL short int modplcsp_getpayloadsize(__data modplcsp_hd *hd) #else short int modplcsp_getpayloadsize(modplcsp_hd *hd) #endif { /* Verifica el estado del modem PLC. */ if (!modplcsp_status(hd)) return 0; /* Devuelve la cantidad mxima de bytes que puede contener un mensaje. */ return hd->payloadsize; }

C.2.52. Archivo __modplcsp_getbyte__.c


/* __modplcsp_getbyte__.c: Implementacin de la funcin __modplcsp_waitbyte__ de la interfaz de la

FernandoArielBeunza79156

295

Tesis de Grado en Ingeniera Informtica


capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include "serial.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Implementacin de funciones privadas. */ /* Funcin __modplcsp_getbyte__: Obtiene un byte recibido por la UART. */ short int __modplcsp_getbyte__(void) { /* Variables. */ int i; short int resp; char c;

/* Contador. */ /* Respuesta. */ /* Caracter recibido. */

/* Obtiene el byte recibido. */ while(1) { c = getchar(); if ((c == '\n') || (c == MODPLC_INITPROMPT) || (c == MODPLC_LAYPROMPT) || (c == MODPLC_NORMPROMPT) || (c == MODPLC_PARAMPROMPT)) return (c << 8); else if (c == '\\') { resp = 0; for(i = 0; i < 2; i++) { c = getchar(); if ((c >= '0') && (c <= '9')) c -= '0'; else if ((c >= 'a') && (c <= 'f')) c = c - 'a' + 10; else if ((c >= 'A') && (c <= 'F')) c = c - 'A' + 10; resp <<= 4; resp |= c; } return resp; } else if ((c >= 0x20) && (c <= 0x7e)) return c; } }

C.2.53. Archivo __modplcsp_getresult__.c


/* __modplcsp_getresult__.c: Implementacin de la funcin __modplcsp_getresult__ de la interfaz de la

296

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include "serial.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Declaracin de funciones privadas. */ void __modplcsp_waitchar__(char); short int __modplcsp_getbyte__(void);

/* Implementacin de funciones privadas. */ /* Funcin __modplcsp_getresult__: Devuelve el resultado de una solicitud. */ #if defined SDCC_MODEL_SMALL short int __modplcsp_getresult__(__data modplcsp_hd *hd) #else short int __modplcsp_getresult__(modplcsp_hd *hd) #endif { /* Variables. */ short int result; short int recvbyte;

/* Resultado de la solicitud. */ /* Byte recibido. */

/* Recibe el resultado de la solicitud. */ result = __modplcsp_getbyte__() & 0x00ff; recvbyte = __modplcsp_getbyte__(); if (!(recvbyte & 0xff00)) result = (result << 8) | (recvbyte & 0x00ff); while(!(recvbyte & 0xff00)) recvbyte = __modplcsp_getbyte__(); /* Verifica el estado del modem PLC. */ if (((char) (recvbyte >> 8)) == MODPLC_INITPROMPT) hd->status = 0; /* Devuelve el resultado recibido. */ return result; }

C.2.54. Archivo __modplcsp_putbyte__.c


/* __modplcsp_putbyte__.c: Implementacin de la funcin __modplcsp_putbyte__ de la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include "serial.h"

FernandoArielBeunza79156

297

Tesis de Grado en Ingeniera Informtica


/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Declaracin de funciones privadas. */ void __modplcsp_puthex__(unsigned char); void __modplcsp_waitchar__(char);

/* Implementacin de funciones privadas. */ /* Funcin __modplcsp_putbyte__: Enva un byte a travs de la UART. */ void __modplcsp_putbyte__(unsigned char val) { __modplcsp_waitchar__(MODPLC_PARAMPROMPT); __modplcsp_puthex__(val); putchar('\n'); }

C.2.55. Archivo __modplcsp_putcmd__.c


/* __modplcsp_putcmd__.c: Implementacin de la funcin __modplcsp_putcmd__ de la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include "serial.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Declaracin de funciones privadas. */ void __modplcsp_waitchar__(char);

/* Implementacin de funciones privadas. */ /* Funcin __modplcsp_putcmd__: Enva un comando a travs de la UART. */ void __modplcsp_putcmd__(char cmd) { putchar(cmd); __modplcsp_waitchar__(cmd); putchar('\n'); }

298

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

C.2.56. Archivo __modplcsp_puthex__.c


/* __modplcsp_puthex__.c: Implementacin de la funcin __modplcsp_puthex__ de la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include "serial.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Declaracin de funciones privadas. */ void __modplcsp_waitchar__(char);

/* Implementacin de funciones privadas. */ /* Funcin __modplcsp_puthex__: Enva un byte codificado en hexadecimal a travs de la UART. */ void __modplcsp_puthex__(unsigned char ch) { /* Variables. */ int i; unsigned char dig;

/* Contador. */ /* Dgito. */

/* Enva un byte codificado en hexadecimal. */ putchar('\\'); __modplcsp_waitchar__('\\'); for(i = 0; i < 2; i++) { dig = ch >> 4; ch <<= 4; if (dig > 9) putchar(dig + 'A' - 10); else putchar(dig + '0'); } }

C.2.57. Archivo __modplcsp_putint__.c


/* __modplcsp_putint__.c: Implementacin de la funcin __modplcsp_putint__ de la interfaz de la capa de sesin del modem PLC. */

FernandoArielBeunza79156

299

Tesis de Grado en Ingeniera Informtica


/* Archivos includos necesarios. */ #include "config.h" #include "serial.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Declaracin de funciones privadas. */ void __modplcsp_puthex__(unsigned char); void __modplcsp_waitchar__(char);

/* Implementacin de funciones privadas. */ /* Funcin __modplcsp_putint__: Enva un entero a travs de la UART. */ void __modplcsp_putint__(short int val) { __modplcsp_waitchar__(MODPLC_PARAMPROMPT); __modplcsp_puthex__((unsigned char) (val >> 8)); __modplcsp_puthex__((unsigned char) (val & 0x00ff)); putchar('\n'); }

C.2.58. Archivo __modplcsp_sendcmd0__.c


/* __modplcsp_sendcmd0__.c: Implementacin de la funcin __modplcsp_sendcmd0__ de la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include "serial.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Declaracin de funciones privadas. */ void __modplcsp_putcmd__(char); void __modplcsp_waitchar__(char); short int __modplcsp_getbyte__(void); #if defined SDCC_MODEL_SMALL short int __modplcsp_getresult__(__data modplcsp_hd *); #else short int __modplcsp_getresult__(modplcsp_hd *); #endif

300

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Implementacin de funciones privadas. */ /* Funcin __modplcsp_sendcmd0__: Enva una solicitud sin parmetros. */ #if defined SDCC_MODEL_SMALL short int __modplcsp_sendcmd0__(__data modplcsp_hd *hd, char cmd) #else short int __modplcsp_sendcmd0__(modplcsp_hd *hd, char cmd) #endif { /* Verifica el estado del modem PLC. */ if (!modplcsp_status(hd)) return 0; /* Solicita verificar la recepcin de un mensaje. */ __modplcsp_putcmd__(cmd); __modplcsp_waitchar__('\n'); /* Devuelve el resultado de la solicitud. */ return __modplcsp_getresult__(hd); }

C.2.59. Archivo __modplcsp_sendcmd1__.c


/* __modplcsp_sendcmd1__.c: Implementacin de la funcin __modplcsp_sendcmd1__ de la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include "serial.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Declaracin de funciones privadas. */ void __modplcsp_putcmd__(char); void __modplcsp_waitchar__(char); short int __modplcsp_getbyte__(void); void __modplcsp_putbyte__(unsigned char); #if defined SDCC_MODEL_SMALL short int __modplcsp_getresult__(__data modplcsp_hd *); #else short int __modplcsp_getresult__(modplcsp_hd *); #endif

/* Implementacin de funciones privadas. */ /* Funcin __modplcsp_sendcmd1__: Enva una solicitud con un parmetro. */ #if defined SDCC_MODEL_SMALL short int __modplcsp_sendcmd1__(__data modplcsp_hd *hd, char cmd,

FernandoArielBeunza79156

301

Tesis de Grado en Ingeniera Informtica


unsigned char param) #else short int __modplcsp_sendcmd1__(modplcsp_hd *hd, char cmd, unsigned char param) #endif { /* Verifica el estado del modem PLC. */ if (!modplcsp_status(hd)) return 0; /* Solicita verificar la recepcin de un mensaje. */ __modplcsp_putcmd__(cmd); __modplcsp_putbyte__(param); __modplcsp_waitchar__('\n'); /* Devuelve el resultado de la solicitud. */ return __modplcsp_getresult__(hd); }

C.2.60. Archivo __modplcsp_waitchar__.c


/* __modplcsp_waitchar__.c: Implementacin de la funcin __modplcsp_waitchar__ de la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include "serial.h"

/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif

/* Archivos includos necesarios. */ #include "modplcsp.h"

/* Implementacin de funciones privadas. */ /* Funcin __modplcsp_waitchar__: Espera la recepcin del caracter especificado. */ void __modplcsp_waitchar__(char ch) { while(getchar() != ch); }

C.2.61. Archivo serial.h


/* serial.h: Declaracin de funciones referentes a la UART. */

#if !defined(__SERIAL_H__) #define __SERIAL_H__

/* Declaracin de funciones pblicas. */

302

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin inituart: Inicializa la UART del microcontrolador. */ void inituart(unsigned char); /* Funcin putchar: Enva un caracter a travs de la UART. */ void putchar(char); /* Funcin poll: Devuelve si hay un caracter almacenado en la UART. */ int poll(void); /* Funcin getchar: Devuelve un caracter recibido por medio de la UART. */ char getchar(void);

#endif

C.2.62. Archivo serial.c


/* serial.c: Implementacin de funciones referentes a la UART. */

/* Archivos includos necesarios. */ #include "serial.h"

/* Definicin de SFR necesarias. */ __sfr __at (0x87) SIO_PCON; __sfr __at (0x89) SIO_TMOD; __sfr __at (0x98) SIO_SCON; __sfr __at (0x99) SIO_SBUF; __sfr __at (0x8B) SIO_TL1; __sfr __at (0x8D) SIO_TH1; __sbit __at (0x8E) SIO_TR1; __sbit __at (0x98) SIO_RI; __sbit __at (0x99) SIO_TI;

/* Funcin inituart: Inicializa la UART del microcontrolador. */ void inituart(unsigned char t1_reload) { /* Inicializa la UART. */ SIO_SCON = 0x50; SIO_TR1 = 0; SIO_TMOD = (SIO_TMOD & 0x0f) | 0x20; SIO_PCON |= 0x80; SIO_TH1 = t1_reload; SIO_TR1 = 1; SIO_TI = 1; }

FernandoArielBeunza79156

303

Tesis de Grado en Ingeniera Informtica


/* Funcin putchar: Enva un caracter a travs de la UART. */ void putchar(char c) { while(!SIO_TI); SIO_TI = 0; SIO_SBUF = c; __asm nop __endasm; } /* Funcin poll: Devuelve si hay un caracter almacenado en la UART. */ int poll(void) { return SIO_RI; } /* Funcin getchar: Devuelve un caracter recibido por medio de la UART. */ char getchar(void) { /* Varaibles. */ char c;

/* Caracter recibido. */

/* Recibe un caracter por medio de la UART. */ while(!poll()); SIO_RI = 0; c = SIO_SBUF; /* Devuelve el caracter recibido. */ return c; }

C.3. Especificacin del cdigo fuente de las bibliotecas de uso del modem PLC (plataforma Windows)
El cdigo fuente que conforma las bibliotecas de uso del modem PLC, se encuentra organizado en los siguientes componentes:

Interfaz capa de aplicacin. Intefaz capa de enlace. Interfaz capa fsica. Driver del modem PLC.

304

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

C.3.1. Interfaz capa de aplicacin modplcap.dll


En esta seccin se detalla el cdigo fuente de la biblioteca que implementa la capa de aplicacin del modem PLC, que se compone de los siguientes archivos:

Archivo config.h: en este archivo se definen parmetros de configuracin de la biblioteca dinmica que implementa la capa de aplicacin del modem PLC que no pueden ser modificados en tiempo de ejecucin. Archivo modplcap.h: en este archivo se declaran primitivas con funcionalidades referentes a la capa de aplicacin del modem PLC. Archivo modplcap.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo modplcap.h. Archivo modplcpp.h: en este archivo se declaran las primitivas correspondientes al manejo de la capa de presentacin. Dichas primitivas brindan la capacidad de trabajar con estructuras de datos independientes de la plataforma. Archivo modplcpp.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo modplcpp.h. Archivo modplcsp.h: en este archivo se declaran las primitivas correspondientes al interfaz con la capa de sesin. Dichas primitivas brindan un conjunto de funcionalidades que permiten la comunicacin con la capa de sesin implementada en el modem PLC por medio del driver del mismo. Archivo modplcsp.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo modplcsp.h.

C.3.1.1. Archivo config.h


/* config.h Definicin de parmetros de configuracin. */

#if !defined(__CONFIG_H__) #define __CONFIG_H__

/* Interfaz con el driver del modem PLC. */ /* Cdigos de operaciones de la interfaz de la capa de sesin. */ #define MODDRVSP_RELEASE 0x00 #define MODDRVSP_PUBLISH 0x01 #define MODDRVSP_SUBSCRIBE 0x02 #define MODDRVSP_LEAVE 0x03 #define MODDRVSP_SEND 0x04 #define MODDRVSP_RECEIVE 0x05 #define MODDRVSP_POLL 0x06 #define MODDRVSP_STATUS 0x07 #define MODDRVSP_GETPAYLOADSIZE 0x08

FernandoArielBeunza79156

305

Tesis de Grado en Ingeniera Informtica


#endif

C.3.1.2. Archivo modplcsp.h


/* modplcsp.h: Declaracin de funciones referentes a la interfaz de la capa de sesin del modem PLC. */

#if !defined(__MODPLCSP_H__) #define __MODPLCSP_H__

/* Archivos includos necesarios. */ #include "config.h" #include <windows.h>

/* Definicin de tipos. */ /* Identificador de grupo. */ typedef unsigned char modplcsp_grpid; /* Manejador de interfaz con la capa de sesin del modem PLC. */ typedef struct { HANDLE hq; /* Manejador de cola de mensajes. */ HANDLE hm; /* Semforo de exclusin mtua. */ HANDLE detectthread; /* Manejador de hilo de deteccin de recepcin. */ size_t payloadsize; /* Cantidad mxima de bytes que puede contener un mensaje. */ void (*recfun) (void *, modplcsp_grpid, void *, size_t, void *); /* Funcin manejadora de mensajes recibidos. */ void *param; /* Parmetros para la funcin manejadora de mensajes recibidos. */ } modplcsp_hd;

/* Declaracin de funciones pblicas. */ /* Funcin modplcsp_init: Inicializa los recursos utilizados por la capa de sesin del modem PLC. */ modplcsp_hd *modplcsp_init(int); /* Funcin modplcsp_release: Libera los recursos utilizados por la capa de sesin del modem PLC. */ int modplcsp_release(modplcsp_hd *); /* Funcin modplcsp_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ int modplcsp_publish(modplcsp_hd *, modplcsp_grpid); /* Funcin modplcsp_subscribe:

306

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Registra el dispositivo como suscriptor del grupo de difusin especificado. */ int modplcsp_subscribe(modplcsp_hd *, modplcsp_grpid); /* Funcin modplcsp_leave: Desvincula el dispositivo del grupo de difusin especificado. */ int modplcsp_leave(modplcsp_hd *, modplcsp_grpid); /* Funcin modplcsp_send: Enva un mensaje por medio de la capa de sesin del modem PLC. */ size_t modplcsp_send(modplcsp_hd *, modplcsp_grpid, unsigned char, const void *, size_t); /* Funcin modplcsp_receive: Recibe un mensaje por medio de la capa de sesin del modem PLC. */ size_t modplcsp_receive(modplcsp_hd *, modplcsp_grpid *, void *, size_t); /* Funcin modplcsp_notify: Define una funcin manejadora de mensajes recibidos. */ int modplcsp_notify(modplcsp_hd *, void (*func)(modplcsp_hd *, modplcsp_grpid, void *, size_t, void *), void *); /* Funcin modplcsp_poll: Verifica la llegada de un nuevo mensaje. */ int modplcsp_poll(modplcsp_hd *); /* Funcin modplcsp_status: Devuelve el estado del modem PLC. */ int modplcsp_status(modplcsp_hd *); /* Funcin modplcsp_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de sesin del modem PLC. */ size_t modplcsp_getpayloadsize(modplcsp_hd *);

#endif

C.3.1.3. Archivo modplcsp.c


/* modplcsp.c: Implementacin de funciones referentes a la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdio.h> #include <windows.h> #include <process.h> #include "modplcsp.h"

FernandoArielBeunza79156

307

Tesis de Grado en Ingeniera Informtica


/* Declaracin de funciones privadas. */ static DWORD WINAPI __modplcsp_detectproc__(LPVOID); static int __modplcsp_sendrecv__(HANDLE, void *, size_t, const void *, size_t);

/* Implementacin de funciones pblicas. */ /* Funcin modplcsp_init: Inicializa los recursos utilizados por la capa de sesin del modem PLC. */ modplcsp_hd *modplcsp_init(int sid) { /* Variables. */ int op; int layer; int result; size_t payloadsize; modplcsp_hd *handle; char qname[256];

/* Identificador de operacin. */ /* Capa a la que se quiere accerder. */ /* Resultado de la solicitud. */ /* Cantidad mxima de bytes que puede contener un mensaje. */ /* Manejador de interfaz con la capa de sesin del modem PLC. */ /* Nombre de la cola de mensajes. */

/* Crea un nuevo manejador de interfaz con la capa de sesin del modem PLC. */ handle = (modplcsp_hd *) malloc(sizeof(modplcsp_hd)); if (!handle) return NULL; /* Inicializa el manejador de interfaz con la capa de sesin del modem PLC. */ while(1) { /* Abre una conexin con la cola de mensajes del driver del modem PLC. */ sprintf(qname, "\\\\.\\pipe\\modemplc%i", sid); handle->hq = CreateFile(qname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (handle->hq == INVALID_HANDLE_VALUE) break; /* Inicializa el manejador de mensajes recibidos. */ handle->param = NULL; handle->recfun = NULL; /* Inicializa semforo de exclusin mtua. */ handle->hm = CreateSemaphore(NULL, 1, 1, NULL); if (handle->hm == INVALID_HANDLE_VALUE) break; /* Solicita acceder a la capa de sesin del modem PLC. */ layer = 3; if (!__modplcsp_sendrecv__(handle->hq, &result, sizeof(result), &layer, sizeof(layer))) break; if (!result) break; /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ op = MODDRVSP_GETPAYLOADSIZE; if (!__modplcsp_sendrecv__(handle->hq, &payloadsize, sizeof(payloadsize), &op, sizeof(op))) break; if (!payloadsize) break; handle->payloadsize = payloadsize; /* Devuelve el manejador creado. */ return handle; } /* No se pudo inicializar la interfaz con la capa de sesin del modem

308

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


PLC. */ CloseHandle(handle->hm); CloseHandle(handle->hq); free(handle); return NULL; } /* Funcin modplcsp_release: Libera los recursos utilizados por la capa de sesin del modem PLC. */ int modplcsp_release(modplcsp_hd *hd) { /* Variables. */ int op; int result;

/* Identificador de operacin. */ /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Libera la funcin manejadora de mensajes recibidos. */ modplcsp_notify(hd, NULL, NULL); /* Solicita la finalizacin del acceso a la capa de sesin del modem PLC. */ op = MODDRVSP_RELEASE; if (!__modplcsp_sendrecv__(hd->hq, &result, sizeof(result), &op, sizeof(op))) return 0; if (!result) return 0; /* Libera los recursos utilizados por la interfaz con la capa de sesin del modem PLC. */ CloseHandle(hd->hm); CloseHandle(hd->hq); free(hd); /* xito. */ return 1; } /* Funcin modplcsp_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ int modplcsp_publish(modplcsp_hd *hd, modplcsp_grpid grpid) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Solicita el registro del dispositivo como publicador. */ result = 0; while(1) { /* Solicita el registro del dispositivo. */ op = MODDRVSP_PUBLISH; if (!__modplcsp_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de grupo. */ __modplcsp_sendrecv__(hd->hq, &result, sizeof(result), &grpid,

FernandoArielBeunza79156

309

Tesis de Grado en Ingeniera Informtica


sizeof(grpid)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve el resultado del registro del dispositivo. */ return result; } /* Funcin modplcsp_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ int modplcsp_subscribe(modplcsp_hd *hd, modplcsp_grpid grpid) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Solicita el registro del dispositivo como suscriptor. */ result = 0; while(1) { /* Solicita el registro del dispositivo. */ op = MODDRVSP_SUBSCRIBE; if (!__modplcsp_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de grupo. */ __modplcsp_sendrecv__(hd->hq, &result, sizeof(result), &grpid, sizeof(grpid)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve el resultado del registro del dispositivo. */ return result; } /* Funcin modplcsp_leave: Desvincula el dispositivo del grupo de difusin especificado. */ int modplcsp_leave(modplcsp_hd *hd, modplcsp_grpid grpid) { /* Variables. */ int op; int result;

/* Identificador de operacin. */ /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Solicita desvincular el dispositivo de un grupo de difusin. */ result = 0; while(1)

310

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


{ /* Solicita desvincular el dispositivo. */ op = MODDRVSP_LEAVE; if (!__modplcsp_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de grupo. */ __modplcsp_sendrecv__(hd->hq, &result, sizeof(result), &grpid, sizeof(grpid)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve el resultado de la desvinculacin del dispositivo. */ return result; } /* Funcin modplcsp_send: Enva un mensaje por medio de la capa de sesin del modem PLC. */ size_t modplcsp_send(modplcsp_hd *hd, modplcsp_grpid grpid, unsigned char nosec, const void *msg, size_t msgsize) { /* Variables. */ int op; /* Identificador de operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Enva un mensaje. */ while(1) { /* Solicita el envo de un mensaje. */ op = MODDRVSP_SEND; if (!__modplcsp_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de grupo. */ if (!__modplcsp_sendrecv__(hd->hq, NULL, 0, &grpid, sizeof(grpid))) break; /* Enva el identificador de mensaje fuera de secuencia. */ if (!__modplcsp_sendrecv__(hd->hq, NULL, 0, &nosec, sizeof(nosec))) break; /* Enva el tamao del mensaje. */ if (!__modplcsp_sendrecv__(hd->hq, NULL, 0, &msgsize, sizeof(msgsize))) break; /* Enva el mensaje. */ if (!__modplcsp_sendrecv__(hd->hq, &msgsize, sizeof(msgsize), msg, msgsize)) break; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve la cantidad de bytes enviados. */ return msgsize; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL);

FernandoArielBeunza79156

311

Tesis de Grado en Ingeniera Informtica


/* No se pudo realizar el envo. */ return 0; } /* Funcin modplcsp_receive: Recibe un mensaje por medio de la capa de sesin del modem PLC. */ size_t modplcsp_receive(modplcsp_hd *hd, modplcsp_grpid *grpid, void *msg, size_t msgsize) { /* Variables. */ int op; /* Identificador de operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Obtiene un mensaje recibido. */ while(1) { /* Solicita recibir un mensaje. */ op = MODDRVSP_RECEIVE; if (!__modplcsp_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva la cantidad de bytes que se quieren recibir del mensaje. */ if (!__modplcsp_sendrecv__(hd->hq, &msgsize, sizeof(msgsize), &msgsize, sizeof(msgsize))) break; if (!msgsize) break; /* Obtiene el identificador de grupo por el cual se recibi el mensaje. */ if (!__modplcsp_sendrecv__(hd->hq, &grpid, sizeof(grpid), NULL, 0)) break; /* Recibe el mensaje. */ if (!__modplcsp_sendrecv__(hd->hq, msg, msgsize, NULL, 0)) break; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve la cantidad de bytes ledos. */ return msgsize; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* No se pudo recibir el mensaje. */ return 0; } /* Funcin modplcsp_notify: Define una funcin manejadora de mensajes recibidos. */ int modplcsp_notify(modplcsp_hd *hd, void (*func)(modplcsp_hd *, modplcsp_grpid, void *, size_t, void *), void *param) { /* Variables. */ DWORD tid; /* Identificador de hilo. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem

312

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


PLC exista. */ if (!hd) return 0; /* Si la funcin manejadora es nula y no hay ninguna funcin manejadora definida previamente no se hace nada. */ if ((!func) && (!hd->recfun)) return 1; /* Si la funcin manejadora no es nula y hay una funcin manejadora previamente definida actualiza la funcin manejadora. */ if ((func) && (hd->recfun)) { WaitForSingleObject(hd->hm, INFINITE); hd->recfun = func; hd->param = param; ReleaseSemaphore(hd->hm, 1, NULL); return 1; } /* Si la funcin manejadora es nula y hay una funcin manejadora definida previamente se elimina esta ltima. */ if ((!func) && (hd->recfun)) { WaitForSingleObject(hd->hm, INFINITE); hd->recfun = NULL; hd->param = param; ReleaseSemaphore(hd->hm, 1, NULL); WaitForSingleObject(hd->detectthread, INFINITE); return 1; } /* Si la funcin manejadora no es nula y no hay una funcin manejadora previamente definida se define la nueva funcin manejadora. */ if ((func) && (!hd->recfun)) { WaitForSingleObject(hd->hm, INFINITE); hd->recfun = func; hd->param = param; hd->detectthread = CreateThread(NULL, 0, __modplcsp_detectproc__, hd, 0, &tid); if (hd->detectthread == INVALID_HANDLE_VALUE) { hd->recfun = NULL; hd->param = NULL; ReleaseSemaphore(hd->hm, 1, NULL); return 0; } ReleaseSemaphore(hd->hm, 1, NULL); return 1; } /* No se pudo definir la funcin manejadora de mensajes recibidos. */ return 0; } /* Funcin modplcsp_poll: Verifica la llegada de un nuevo mensaje. */ int modplcsp_poll(modplcsp_hd *hd) { /* Variables. */ int op; int result;

/* Identificador de operacin. */ /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE);

FernandoArielBeunza79156

313

Tesis de Grado en Ingeniera Informtica


/* Solicita verificar la recepcin de un mensaje. */ op = MODDRVSP_POLL; if (!__modplcsp_sendrecv__(hd->hq, &result, sizeof(result), &op, sizeof(op))) result = 0; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve el resultado de la solicitud. */ return result; } /* Funcin modplcsp_status: Devuelve el estado del modem PLC. */ int modplcsp_status(modplcsp_hd *hd) { /* Variables. */ int op; int result;

/* Identificador de operacin. */ /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Obtiene el estado del modem PLC. */ op = MODDRVSP_STATUS; if (!__modplcsp_sendrecv__(hd->hq, &result, sizeof(result), &op, sizeof(op))) result = 0; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve el estado del modem PLC. */ return result; } /* Funcin modplcsp_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de sesin del modem PLC. */ size_t modplcsp_getpayloadsize(modplcsp_hd *hd) { /* Variables. */ int op; size_t payloadsize;

/* Identificador de operacin. */ /* Cantidad de bytes que puede contener un mensaje. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ op = MODDRVSP_GETPAYLOADSIZE; if (!__modplcsp_sendrecv__(hd->hq, &payloadsize, sizeof(payloadsize), &op, sizeof(op))) payloadsize = 0;

314

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve la cantidad mxima de bytes que puede contener un mensaje. */ return payloadsize; } /* Implementacin de funciones privadas. */ /* Funcin __modplcsp_detectproc__: Verifica la existencia de un mensaje recibido disponible para ser ledo. */ static DWORD WINAPI __modplcsp_detectproc__(LPVOID param) { /* Variables. */ int op; int result; int captureflag; size_t msgsize; modplcsp_grpid grpid; modplcsp_hd *hd; void (*func)(void *, modplcsp_grpid, void *, size_t, void *); unsigned char *msg;

/* Identificador de operacin. */ /* Resultado de la operacin. */ /* Indicador de recepcin de un mensaje. */ /* Tamao del mensaje. */ /* Identificador de grupo. */ /* Manejador de interfaz con la capa de sesin del modem PLC. */ /* Funcin manejadora de mensajes recibidos. */ /* Puntero al mensaje. */

/* Carga el manejador de interfaz con la capa de sesin del modem PLC. */ hd = (modplcsp_hd *) param; /* Verifica la existencia de un mensaje recibido. */ while(1) { /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Verifica la recepcin de un mensaje. */ func = hd->recfun; if (!func) break; op = MODDRVSP_POLL; if (__modplcsp_sendrecv__(hd->hq, &result, sizeof(result), &op, sizeof(op))) captureflag = result; /* Recibe el mensaje. */ while(captureflag) { /* Solicita la recepcin de un mensaje. */ op = MODDRVSP_RECEIVE; if (!__modplcsp_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva la cantidad de bytes que se solicita recibir del mensaje. */ msgsize = hd->payloadsize; if (!__modplcsp_sendrecv__(hd->hq, &msgsize, sizeof(msgsize), &msgsize, sizeof(msgsize))) break; if (!msgsize) break; /* Recibe la direccin de origen del mensaje. */ if (!__modplcsp_sendrecv__(hd->hq, &grpid, sizeof(grpid), NULL, 0)) break; /* Recibe el mensaje. */ msg = (unsigned char *) malloc(msgsize * sizeof(unsigned char)); if (!msg)

FernandoArielBeunza79156

315

Tesis de Grado en Ingeniera Informtica


{ captureflag = 0; break; } __modplcsp_sendrecv__(hd->hq, msg, msgsize, NULL, 0); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Verifica si se ha detectado la recepcin de un mensaje para invocar a la funcin manejadora de mensajes recibidos. */ if (captureflag) { func(hd, grpid, msg, msgsize, hd->param); free(msg); captureflag = 0; } } /* Fin de ejecucin del hilo de deteccin de recepcin. */ ReleaseSemaphore(hd->hm, 1, NULL); return 0; } /* Funcin __modplcsp_sendrecv__: Intercambia datos con el driver del modem PLC. */ static int __modplcsp_sendrecv__(HANDLE hq, void *outdata, size_t outsize, const void *indata, size_t insize) { /* Variables. */ size_t last; /* Cantidad de bytes enviados o recibidos. */ size_t sent; /* Cantidad de bytes enviados. */ size_t received; /* Cantidad de bytes recibidos. */

/* Verifica que el manejador de cola de mensajes exista. */ if (hq == INVALID_HANDLE_VALUE) return 0; /* Enva la operacin. */ sent = 0; while((indata) && (sent < insize)) { if (!WriteFile(hq, indata, insize, &last, NULL)) return 0; sent += last; } /* Recibe la respuesta. */ received = 0; while((outdata) && (received < outsize)) { if (!ReadFile(hq, outdata, outsize, &last, NULL)) return 0; received += last; } /* xito. */ return 1; }

C.3.1.4. Archivo modplcpp.h


/* modplcpp.h:

316

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Declaracin de funciones referentes a la capa de presentacin del modem PLC. */

#if !defined(__MODPLCPP_H__) #define __MODPLCPP_H__

/* Archivos includos necesarios. */ #include "config.h" #include "modplcsp.h"

/* Definicin de tipos. */ /* Identificador de grupo. */ typedef unsigned char modplcpp_grpid; /* Tipo de mensaje. */ typedef unsigned char modplcpp_mtype; /* Tipo de campo. */ typedef unsigned char modplcpp_ftype; /* Estructura del mensaje. */ typedef struct { unsigned short int startoffset; unsigned short int endoffset; modplcpp_grpid grpid; modplcpp_mtype mtype; void *pphd; unsigned char *dat; } modplcpp_msg; /* Manejador de capa de presentacin. */ typedef struct { size_t payloadsize; modplcpp_grpid grpid;

/* /* /* /* /*

Comienzo del mensaje. */ Fin del mensaje. */ Identificador de grupo. */ Tipo de mensaje. */ Manejador de capa de presentacin. */ /* Puntero al contenido del mensaje. */

modplcsp_hd *modsphd; void (*recfun) (void *, modplcpp_msg *, void *); void *param;

/* Cantidad mxima de bytes que puede contener un mensaje. */ /* Identificador de grupo del mensaje almacenado en el buffer. */ /* Manejador de interfaz con la capa de sesin del modem PLC. */ /* Funcin manejadora de mensajes recibidos. */ /* Parmetros para la funcin manejadora de mensajes recibidos. */ /* Puntero al buffer de campos recibidos. */

modplcpp_msg buffer; } modplcpp_hd;

/* Definicin de constantes. */ /* Tipo de mensaje. */ #define MODPLCPP_SECMSG #define MODPLCPP_NOSECMSG /* Tipos de datos. */ #define MODPLCPP_NULLTYPE #define MODPLCPP_CHARTYPE #define MODPLCPP_SINT8TYPE #define MODPLCPP_UINT8TYPE #define MODPLCPP_SINT16TYPE

0x00 0x01

0x00 0x01 0x02 0x03 0x04

FernandoArielBeunza79156

317

Tesis de Grado en Ingeniera Informtica


#define #define #define #define MODPLCPP_UINT16TYPE MODPLCPP_SINT32TYPE MODPLCPP_UINT32TYPE MODPLCPP_FLOATTYPE 0x05 0x06 0x07 0x08

/* Declaracin de funciones pblicas. */ /* Funcin modplcpp_init: Inicializa los recursos utilizado por la capa de presentacin del modem PLC. */ modplcpp_hd *modplcpp_init(int); /* Funcin modplcpp_release: Libera los recursos utilizados por la capa de presentacin del modem PLC. */ int modplcpp_release(modplcpp_hd *); /* Funcin modplcpp_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ int modplcpp_publish(modplcpp_hd *, modplcpp_grpid); /* Funcin modplcpp_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ int modplcpp_subscribe(modplcpp_hd *, modplcpp_grpid); /* Funcin modplcpp_leave: Desvincula el dispositivo del grupo de difusin especificado. */ int modplcpp_leave(modplcpp_hd *, modplcpp_grpid); /* Funcin modplcpp_newmsg: Crea un nuevo mensaje. */ int modplcpp_newmsg(modplcpp_hd *, modplcpp_msg *, modplcpp_grpid, modplcpp_mtype); /* Funcin modplcpp_copymsg: Crea un copia de un mensaje. */ int modplcpp_copymsg(modplcpp_msg *, modplcpp_msg *); /* Funcin modplcpp_putfield: Agrega un nuevo campo al mensaje. */ int modplcpp_putfield(modplcpp_msg *, modplcpp_ftype, unsigned char, const void *); /* Funcin modplcpp_sendmsg: Enva un mensaje por medio de la capa de presentacin. */ int modplcpp_sendmsg(modplcpp_msg *); /* Funcin modplcpp_receivemsg: Recibe un mensaje por medio de la capa de presentacin. */ int modplcpp_receivemsg(modplcpp_hd *, modplcpp_msg *);

318

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin modplcpp_getfield: Extrae un campo del mensaje. */ int modplcpp_getfield(modplcpp_msg *, modplcpp_ftype *, unsigned char *, void *); /* Funcin modplcpp_getgrpid: Devuelve el identificador de grupo del mensaje. */ modplcpp_grpid modplcpp_getgrpid(modplcpp_msg *); /* Funcin modplcpp_destroymsg: Destruye un mensaje. */ int modplcpp_destroymsg(modplcpp_msg *); /* Funcin modplcpp_notify: Define una funcin manejadora de mensajes recibidos. */ int modplcpp_notify(modplcpp_hd *, void (*func)(modplcpp_hd *, modplcpp_msg *, void *), void *); /* Funcin modplcpp_poll: Verifica la llegada de un nuevo mensaje. */ int modplcpp_poll(modplcpp_hd *); /* Funcin modplcpp_status: Devuelve el estado del modem PLC. */ int modplcpp_status(modplcpp_hd *);

#endif

C.3.1.5. Archivo modplcpp.c


/* modplcpp.c: Implementacin de funciones referentes a la capa de presentacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include "modplcsp.h" #include "modplcpp.h"

/* Declaracin de funciones privadas. */ static void __modplcpp_procmsg__(modplcsp_hd *, modplcsp_grpid, const void *, size_t, void *);

/* Implementacin de funciones pblicas. */ /* Funcin modplcpp_init: Inicializa los recursos utilizado por la capa de presentacin del modem PLC. */

FernandoArielBeunza79156

319

Tesis de Grado en Ingeniera Informtica


modplcpp_hd *modplcpp_init(int sid) { /* Variables. */ modplcpp_hd *handle;

/* Manejador de capa de presentacin. */

/* Crea un nuevo manejador de capa de presentacin. */ handle = (modplcpp_hd *) malloc(sizeof(modplcpp_hd)); if (!handle) return NULL; /* Inicializa el manejador de capa de presentacin. */ while(1) { /* Inicializa el manejador de interfaz con la capa de sesin del modem PLC. */ handle->modsphd = modplcsp_init(sid); if (!handle->modsphd) break; /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ handle->payloadsize = modplcsp_getpayloadsize(handle->modsphd); if (!handle->payloadsize) break; /* Define un manejador de mensajes recibidos por la capa de sesin. */ if (!modplcsp_notify(handle->modsphd, __modplcpp_procmsg__, handle)) break; /* Inicializa el manejador de mensajes recibidos. */ handle->param = NULL; handle->recfun = NULL; /* Devuelve el manejador creado. */ return handle; } /* No se pudo inicializar la interfaz con la capa de presentacin. */ modplcsp_release(handle->modsphd); free(handle); return NULL; } /* Funcin modplcpp_release: Libera los recursos utilizados por la capa de presentacin del modem PLC. */ int modplcpp_release(modplcpp_hd *hd) { /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Libera el manejador de mensajes recibidos. */ modplcsp_notify(hd->modsphd, NULL, NULL); /* Libera la interfaz con la capa de sesin del modem PLC. */ modplcsp_release(hd->modsphd); /* Libera los recursos utilizados por la capa de presentacin. */ free(hd); /* xito. */ return 1; } /* Funcin modplcpp_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ int modplcpp_publish(modplcpp_hd *hd, modplcpp_grpid grpid) { /* Verifica que el manejador de la capa de presentacin exista. */

320

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


if (!hd) return 0; /* Registra el dispositivo como publicador del grupo de difusin especificado. */ return modplcsp_publish(hd->modsphd, grpid); } /* Funcin modplcpp_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ int modplcpp_subscribe(modplcpp_hd *hd, modplcpp_grpid grpid) { /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Registra el dispositivo como suscriptor del grupo de difusin especificado. */ return modplcsp_subscribe(hd->modsphd, grpid); } /* Funcin modplcpp_leave: Desvincula el dispositivo del grupo de difusin especificado. */ int modplcpp_leave(modplcpp_hd *hd, modplcpp_grpid grpid) { /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Desvincula el dispositivo del grupo de difusin especificado. */ return modplcsp_leave(hd->modsphd, grpid); } /* Funcin modplcpp_newmsg: Crea un nuevo mensaje. */ int modplcpp_newmsg(modplcpp_hd *hd, modplcpp_msg *msg, modplcpp_grpid grpid, modplcpp_mtype mtype) { /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Asigna memoria para almacenar el contenido del mensaje. */ msg->dat = (unsigned char *) malloc(hd->payloadsize * sizeof(unsigned char)); if (!msg->dat) return 0; /* Inicializa el mensaje. */ msg->startoffset = 0; msg->endoffset = 0; msg->grpid = grpid; msg->mtype = mtype; msg->pphd = hd; return 1; } /* Funcin modplcpp_copymsg: Crea un copia de un mensaje. */ int modplcpp_copymsg(modplcpp_msg *dest, modplcpp_msg *src) { /* Verifica que el puntero al mensaje original no sea nulo. */ if (!src) return 0; /* Verifica que el puntero a la copia del mensaje no sea nulo. */

FernandoArielBeunza79156

321

Tesis de Grado en Ingeniera Informtica


if (!dest) return 0; /* Asigna memoria para almacenar el contenido del mensaje. */ dest->dat = (unsigned char *) malloc(((modplcpp_hd *) src->pphd)->payloadsize * sizeof(unsigned char)); if (!dest->dat) return 0; /* Inicializa la copia del mensaje. */ dest->startoffset = src->startoffset; dest->endoffset = src->endoffset; dest->grpid = src->grpid; dest->mtype = src->mtype; dest->pphd = src->pphd; memcpy(dest->dat, src->dat, src->endoffset); return 1; } /* Funcin modplcpp_putfield: Agrega un nuevo campo al mensaje. */ int modplcpp_putfield(modplcpp_msg *msg, modplcpp_ftype type, unsigned char count, const void *dat) { /* Variables. */ unsigned char *ptr; /* Puntero a los datos. */ size_t msgsize; /* Tamao del mensaje. */

/* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Inicializa el puntero a los datos. */ ptr = (unsigned char *) dat; /* Verifica si el nuevo campo puede entrar en el mensaje. */ msgsize = msg->endoffset; msgsize += sizeof(modplcpp_ftype); msgsize += sizeof(unsigned char); if ((type == MODPLCPP_CHARTYPE) || (type == MODPLCPP_UINT8TYPE)) msgsize += count * sizeof(unsigned char); else if (type == MODPLCPP_SINT8TYPE) msgsize += count * sizeof(char); else if ((type == MODPLCPP_SINT16TYPE) || (type == MODPLCPP_UINT16TYPE)) msgsize += count * sizeof(unsigned short int); else if ((type == MODPLCPP_SINT32TYPE) || (type == MODPLCPP_UINT32TYPE)) msgsize += count * sizeof(unsigned long int); else if (type == MODPLCPP_FLOATTYPE) msgsize += count * sizeof(float); else return 0; if (msgsize > ((modplcpp_hd *) (msg->pphd))->payloadsize) return 0; /* Agrega el tipo de dato. */ *(msg->dat + msg->endoffset) = type; msg->endoffset += sizeof(modplcpp_ftype); /* Agrega la cantidad de datos. */ *(msg->dat + msg->endoffset) = count; msg->endoffset += sizeof(unsigned char); /* Agrega datos tipo caracter o entero de 8 bits sin signo. */ if ((type == MODPLCPP_CHARTYPE) || (type == MODPLCPP_UINT8TYPE)) { while(count--) { *(msg->dat + msg->endoffset) = *ptr; ptr += sizeof(unsigned char); msg->endoffset += sizeof(unsigned char); }

322

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


} /* Agrega datos tipo entero de 8 bits con signo. */ else if (type == MODPLCPP_SINT8TYPE) { while(count--) { *(msg->dat + msg->endoffset) = *ptr; ptr += sizeof(char); msg->endoffset += sizeof(char); } } /* Agrega datos tipo entero de 16 bits. */ else if ((type == MODPLCPP_SINT16TYPE) || (type == MODPLCPP_UINT16TYPE)) { while(count--) { *(msg->dat + msg->endoffset + 0) = *(ptr + 1); *(msg->dat + msg->endoffset + 1) = *(ptr + 0); ptr += sizeof(unsigned short int); msg->endoffset += sizeof(unsigned short int); } } /* Agrega datos tipo entero de 32 bits. */ else if ((type == MODPLCPP_SINT32TYPE) || (type == MODPLCPP_UINT32TYPE)) { while(count--) { *(msg->dat + msg->endoffset + 0) = *(ptr + 3); *(msg->dat + msg->endoffset + 1) = *(ptr + 2); *(msg->dat + msg->endoffset + 2) = *(ptr + 1); *(msg->dat + msg->endoffset + 3) = *(ptr + 0); ptr += sizeof(unsigned long int); msg->endoffset += sizeof(unsigned long int); } } /* Agrega datos tipo punto flotante. */ else if (type == MODPLCPP_FLOATTYPE) { while(count--) { *(msg->dat + msg->endoffset) = *ptr; ptr += sizeof(float); msg->endoffset += sizeof(float); } } /* xito. */ return 1; } /* Funcin modplcpp_sendmsg: Enva un mensaje por medio de la capa de presentacin. */ int modplcpp_sendmsg(modplcpp_msg *msg) { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Enva un mensaje. */ if (modplcsp_send(((modplcpp_hd *) (msg->pphd))->modsphd, msg->grpid, msg->mtype, msg->dat, msg->endoffset) == msg->endoffset) return 1; return 0; } /* Funcin modplcpp_receivemsg: Recibe un mensaje por medio de la capa de presentacin. */ int modplcpp_receivemsg(modplcpp_hd *hd, modplcpp_msg *msg)

FernandoArielBeunza79156

323

Tesis de Grado en Ingeniera Informtica


{ /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Asigna memoria para almacenar el contenido del mensaje. */ msg->dat = (unsigned char *) malloc(hd->payloadsize * sizeof(unsigned char)); if (!msg->dat) return 0; /* Espera la llegada de un mensaje. */ while(!modplcpp_poll(hd)); /* Devuelve el mensaje almacenado en el buffer de recepcin. */ if (msg) { msg->grpid = hd->buffer.grpid; msg->startoffset = hd->buffer.startoffset; msg->endoffset = hd->buffer.endoffset; msg->pphd = hd; memcpy(msg->dat, hd->buffer.dat, hd->buffer.endoffset); } hd->buffer.endoffset = 0; free(hd->buffer.dat); /* xito. */ return 1; } /* Funcin modplcpp_getfield: Extrae un campo del mensaje. */ int modplcpp_getfield(modplcpp_msg *msg, modplcpp_ftype *type, unsigned char *count, void *dat) { /* Variables. */ unsigned char c; /* Contador. */ unsigned char *ptr; /* Puntero a los datos. */

/* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Inicializa el puntero a los datos. */ ptr = (unsigned char *) dat; /* Extrae el tipo de dato. */ *type = *(msg->dat + msg->startoffset); msg->startoffset += sizeof(modplcpp_ftype); /* Extrae la cantidad de datos. */ c = *(msg->dat + msg->startoffset); *count = c; msg->startoffset += sizeof(unsigned char); /* Agrega datos tipo caracter o entero de 8 bits. */ if ((*type == MODPLCPP_CHARTYPE) || (*type == MODPLCPP_SINT8TYPE) || (*type == MODPLCPP_UINT8TYPE)) { while(c --) { *ptr = *(msg->dat + msg->startoffset); ptr += sizeof(unsigned char); msg->startoffset += sizeof(unsigned char); } return 1; }

324

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Agrega datos tipo entero de 16 bits. */ if ((*type == MODPLCPP_SINT16TYPE) || (*type == MODPLCPP_UINT16TYPE)) { while(c --) { *(ptr + 1) = *(msg->dat + msg->startoffset + 0); *(ptr + 0) = *(msg->dat + msg->startoffset + 1); ptr += sizeof(unsigned short int); msg->startoffset += sizeof(unsigned short int); } return 1; } /* Agrega datos tipo entero de 32 bits. */ if ((*type == MODPLCPP_SINT32TYPE) || (*type == MODPLCPP_UINT32TYPE)) { while(c --) { *(ptr + 3) = *(msg->dat + msg->startoffset + 0); *(ptr + 2) = *(msg->dat + msg->startoffset + 1); *(ptr + 1) = *(msg->dat + msg->startoffset + 2); *(ptr + 0) = *(msg->dat + msg->startoffset + 3); ptr += sizeof(unsigned long int); msg->startoffset += sizeof(unsigned long int); } return 1; } /* Agrega datos tipo punto flotante. */ if (*type == MODPLCPP_FLOATTYPE) { while(c --) { *ptr = *(msg->dat + msg->startoffset); ptr += sizeof(float); msg->startoffset += sizeof(float); } return 1; } /* Tipo de dato desconocido. */ msg->startoffset -= sizeof(unsigned char); msg->startoffset -= sizeof(modplcpp_ftype); return 0; } /* Funcin modplcpp_getgrpid: Devuelve el identificador de grupo del mensaje. */ modplcpp_grpid modplcpp_getgrpid(modplcpp_msg *msg) { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Devuelve el identificador de grupo del mensaje. */ return msg->grpid; } /* Funcin modplcpp_destroymsg: Destruye un mensaje. */ int modplcpp_destroymsg(modplcpp_msg *msg) { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Elimina el contenido del mensaje. */ if (!msg->dat) return 0; free(msg->dat);

FernandoArielBeunza79156

325

Tesis de Grado en Ingeniera Informtica


msg->dat = NULL; return 1; } /* Funcin modplcpp_notify: Define una funcin manejadora de mensajes recibidos. */ int modplcpp_notify(modplcpp_hd *hd, void (*func)(modplcpp_hd *, modplcpp_msg *, void *), void *param) { /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Define un manejador de mensajes recibidos. */ hd->recfun = func; hd->param = param; return 1; } /* Funcin modplcpp_poll: Verifica la llegada de un nuevo mensaje. */ int modplcpp_poll(modplcpp_hd *hd) { /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Verifica la llegada de un nuevo mensaje. */ return (hd->buffer.endoffset != 0); } /* Funcin modplcpp_status: Devuelve el estado del modem PLC. */ int modplcpp_status(modplcpp_hd *hd) { /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Devuelve el estado del modem PLC. */ return modplcsp_status(hd->modsphd); }

/* Implementacin de funciones privadas. */ /* Funcin __modplcpp_procmsg__: Procesa un mensaje recibido por medio de la capa de sesin. */ static void __modplcpp_procmsg__(modplcsp_hd *hd, modplcsp_grpid grpid, const void *msg, size_t msgsize, void *param) { /* Variables. */ modplcpp_hd *pphd; /* Manejador de capa de presentacin. */

/* Carga el manejador de capa de presentacin. */ pphd = (modplcpp_hd *) param; /* Verifica si el buffer se encuentra lleno. */ if (pphd->buffer.endoffset != 0) return; /* Reserva memoria para almacenar el mensaje recibido. */ pphd->buffer.dat = (unsigned char *) malloc(msgsize * sizeof(unsigned char));

326

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


if (!pphd->buffer.dat) return; /* Acepta el mensaje recibido. */ pphd->buffer.grpid = grpid; pphd->buffer.startoffset = 0; pphd->buffer.endoffset = msgsize; pphd->buffer.pphd = pphd; memcpy(pphd->buffer.dat, msg, msgsize); /* Invoca a la funcin de atencin de recepcin de mensajes registrada. */ if (!pphd->recfun) return; pphd->recfun(pphd, &(pphd->buffer), pphd->param); pphd->buffer.endoffset = 0; free(pphd->buffer.dat); }

C.3.1.6. Archivo modplcap.h


/* modplcap.h: Declaracin de funciones referentes a la interfaz de la capa de aplicacin del modem PLC. */

#if !defined(__MODPLCAP_H__) #define __MODPLCAP_H__

/* Archivos includos necesarios. */ #include <windows.h>

/* Definicin de tipos. */ /* Identificador de grupo. */ typedef unsigned char modplcap_grpid; /* Identificador de mensaje. */ typedef unsigned short int modplcap_msgid; /* Tipo de campo. */ typedef unsigned char modplcap_ftype; /* Estructura del mensaje. */ typedef struct { modplcap_msgid msgid; void *msg; } modplcap_msg; /* Manejador de capa de aplicacin. */ typedef struct { int msgflag; modplcap_grpid grpid;

/* Identificador de mensaje. */ /* Puntero al mensaje. */

void *pphd; void (*recfun) (void *, modplcap_msg *, void *); void *param;

/* Indicador de mensaje en el buffer. */ /* Identificador de grupo del mensaje almacenado en el buffer. */ /* Puntero al manejador de capa de presentacin. */ /* Funcin manejadora de mensajes recibidos. */ /* Parmetros para la funcin manejadora de mensajes recibidos. */ /* Puntero al buffer de campos

modplcap_msg buffer;

FernandoArielBeunza79156

327

Tesis de Grado en Ingeniera Informtica


recibidos. */ } modplcap_hd;

/* Definicin de constantes. */ /* Tipos de datos. */ #define MODPLCAP_NULLTYPE #define MODPLCAP_CHARTYPE #define MODPLCAP_SINT8TYPE #define MODPLCAP_UINT8TYPE #define MODPLCAP_SINT16TYPE #define MODPLCAP_UINT16TYPE #define MODPLCAP_SINT32TYPE #define MODPLCAP_UINT32TYPE #define MODPLCAP_FLOATTYPE

0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08

/* Declaracin de funciones pblicas. */ #if !defined(__MODPLCAP_DLL__) /* Funcin modplcap_init: Inicializa los recursos utilizados por la capa de aplicacin del modem PLC. */ static modplcap_hd * (*modplcap_init)(int); /* Funcin modplcap_release: Libera los recursos utilizados por la capa de aplicacin del modem PLC. */ static int (*modplcap_release)(modplcap_hd *); /* Funcin modplcap_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ static int (*modplcap_publish)(modplcap_hd *, modplcap_grpid); /* Funcin modplcap_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ static int (*modplcap_subscribe)(modplcap_hd *, modplcap_grpid); /* Funcin modplcap_leave: Desvincula el dispositivo del grupo de difusin especificado. */ static int (*modplcap_leave)(modplcap_hd *, modplcap_grpid); /* Funcin modplcap_newmsg: Crea un nuevo mensaje. */ static int (*modplcap_newmsg)(modplcap_hd *, modplcap_msg *, modplcap_grpid, modplcap_msgid); /* Funcin modplcap_copymsg: Crea un copia de un mensaje. */ static int (*modplcap_copymsg)(modplcap_msg *, modplcap_msg *); /* Funcin modplcap_putfield: Agrega un nuevo campo al mensaje. */ static int (*modplcap_putfield)(modplcap_msg *, modplcap_ftype, unsigned char, const void *);

328

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin modplcap_sendmsg: Enva un mensaje por medio de la capa de aplicacin. */ static int (*modplcap_sendmsg)(modplcap_msg *); /* Funcin modplcap_receivemsg: Recibe un mensaje por medio de la capa de aplicacin. */ static int (*modplcap_receivemsg)(modplcap_hd *, modplcap_msg *); /* Funcin modplcap_getfield: Extrae un campo del mensaje. */ static int (*modplcap_getfield)(modplcap_msg *, modplcap_ftype *, unsigned char *, void *); /* Funcin modplcap_getgrpid: Devuelve el identificador de grupo del mensaje. */ static modplcap_grpid (*modplcap_getgrpid)(modplcap_msg *); /* Funcin modplcap_getmsgid: Devuelve el identificador de mensaje. */ static modplcap_msgid (*modplcap_getmsgid)(modplcap_msg *); /* Funcin modplcap_destroymsg: Destruye un mensaje. */ static int (*modplcap_destroymsg)(modplcap_msg *); /* Funcin modplcap_notify: Define una funcin manejadora de mensajes recibidos. */ static int (*modplcap_notify)(modplcap_hd *, void (*func)(modplcap_hd *, modplcap_msg *, void *), void *); /* Funcin modplcap_poll: Verifica la llegada de un nuevo mensaje. */ static int (*modplcap_poll)(modplcap_hd *); /* Funcin modplcap_status: Devuelve el estado del modem PLC. */ static int (*modplcap_status)(modplcap_hd *);

/* Implementacin de funciones pblicas. */ /* Funcin modplcap_loadlib: Carga la bliblioteca dinmica referente a la capa de aplicacin del modem PLC. */ static int modplcap_loadlib(void) { /* Variables. */ struct HINSTANCE__ *hlib;

/* Manejador de biblioteca dinmica. */

FernandoArielBeunza79156

329

Tesis de Grado en Ingeniera Informtica


/* Carga la biblioteca. */ hlib = NULL; modplcap_init = NULL; modplcap_release = NULL; modplcap_publish = NULL; modplcap_subscribe = NULL; modplcap_leave = NULL; modplcap_newmsg = NULL; modplcap_copymsg = NULL; modplcap_putfield = NULL; modplcap_sendmsg = NULL; modplcap_receivemsg = NULL; modplcap_getfield = NULL; modplcap_getgrpid = NULL; modplcap_getmsgid = NULL; modplcap_destroymsg = NULL; modplcap_notify = NULL; modplcap_poll = NULL; modplcap_status = NULL; hlib = LoadLibrary("MODPLCAP"); if (!hlib) return 0; modplcap_init = (modplcap_hd * (*)(int)) GetProcAddress(hlib, "modplcap_init"); modplcap_release = (int (*)(modplcap_hd *)) GetProcAddress(hlib, "modplcap_release"); modplcap_publish = (int (*)(modplcap_hd *, modplcap_grpid)) GetProcAddress(hlib, "modplcap_publish"); modplcap_subscribe = (int (*)(modplcap_hd *, modplcap_grpid)) GetProcAddress(hlib, "modplcap_subscribe"); modplcap_leave = (int (*)(modplcap_hd *, modplcap_grpid)) GetProcAddress(hlib, "modplcap_leave"); modplcap_newmsg = (int (*)(modplcap_hd *, modplcap_msg *, modplcap_grpid, modplcap_msgid)) GetProcAddress(hlib, "modplcap_newmsg"); modplcap_copymsg = (int (*)(modplcap_msg *, modplcap_msg *)) GetProcAddress(hlib, "modplcap_copymsg"); modplcap_putfield = (int (*)(modplcap_msg *, modplcap_ftype, unsigned char, const void *)) GetProcAddress(hlib, "modplcap_putfield"); modplcap_sendmsg = (int (*)(modplcap_msg *)) GetProcAddress(hlib, "modplcap_sendmsg"); modplcap_receivemsg = (int (*)(modplcap_hd *, modplcap_msg *)) GetProcAddress(hlib, "modplcap_receivemsg"); modplcap_getfield = (int (*)(modplcap_msg *, modplcap_ftype *, unsigned char *, void *)) GetProcAddress(hlib, "modplcap_getfield"); modplcap_getgrpid = (modplcap_grpid (*)(modplcap_msg *)) GetProcAddress(hlib, "modplcap_getgrpid"); modplcap_getmsgid = (modplcap_msgid (*)(modplcap_msg *)) GetProcAddress(hlib, "modplcap_getmsgid"); modplcap_destroymsg = (int (*)(modplcap_msg *)) GetProcAddress(hlib, "modplcap_destroymsg"); modplcap_notify = (int (*)(modplcap_hd *, void (*func)(modplcap_hd *, modplcap_msg *, void *), void *)) GetProcAddress(hlib, "modplcap_notify"); modplcap_poll = (int (*)(modplcap_hd *)) GetProcAddress(hlib, "modplcap_poll"); modplcap_status = (int (*)(modplcap_hd *)) GetProcAddress(hlib, "modplcap_status"); /* Verifica que todas las funciones de la biblioteca se hayan cargado. */ if ((!modplcap_init) || (!modplcap_release) || (!modplcap_publish) || (!modplcap_subscribe) || (!modplcap_leave) || (!modplcap_newmsg) || (!modplcap_copymsg) || (!modplcap_putfield) || (!modplcap_sendmsg) || (!modplcap_receivemsg) || (!modplcap_getfield) || (!modplcap_getgrpid) || (!modplcap_getmsgid) || (!modplcap_destroymsg) || (!modplcap_notify) || (!modplcap_poll) || (!modplcap_status)) return 0; /* xito. */

330

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


return 1; } #endif

#endif

C.3.1.7. Archivo modplcap.c


/* modplcap.c: Implementacin de funciones referentes a la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #define __MODPLCAP_DLL__ #include "config.h" #include <stdio.h> #include <windows.h> #include <process.h> #include "modplcpp.h" #include "modplcap.h"

/* Declaracin de funciones pblicas. */ modplcap_hd *modplcap_init(int); int modplcap_release(modplcap_hd *); int modplcap_publish(modplcap_hd *, modplcap_grpid); int modplcap_subscribe(modplcap_hd *, modplcap_grpid); int modplcap_leave(modplcap_hd *, modplcap_grpid); int modplcap_newmsg(modplcap_hd *, modplcap_msg *, modplcap_grpid, modplcap_msgid); int modplcap_putfield(modplcap_msg *, modplcap_ftype, unsigned char, const void *); int modplcap_sendmsg(modplcap_msg *); int modplcap_receivemsg(modplcap_hd *, modplcap_msg *); int modplcap_getfield(modplcap_msg *, modplcap_ftype *, unsigned char *, void *); modplcap_grpid modplcap_getgrpid(modplcap_msg *); modplcap_msgid modplcap_getmsgid(modplcap_msg *); int modplcap_destroymsg(modplcap_msg *); int modplcap_notify(modplcap_hd *, void (*func)(modplcap_hd *, modplcap_msg *, void *), void *); int modplcap_poll(modplcap_hd *); int modplcap_status(modplcap_hd *);

/* Declaracin de funciones privadas. */ static void __modplcap_procmsg__(modplcpp_hd *, modplcpp_msg *, void *);

/* Implementacin de funciones pblicas. */ /* Funcin modplcap_init: Inicializa los recursos utilizados por la capa de aplicacin del modem PLC. */ modplcap_hd *modplcap_init(int sid) { /* Variables. */ modplcap_hd *handle;

/* Manejador de capa de aplicacin. */

/* Crea un nuevo manejador de capa de aplicacin. */ handle = (modplcap_hd *) malloc(sizeof(modplcap_hd));

FernandoArielBeunza79156

331

Tesis de Grado en Ingeniera Informtica


if (!handle) return NULL; /* Inicializa el manejador de capa de aplicacin. */ while(1) { /* Inicializa el manejador de capa de presentancin. */ handle->pphd = modplcpp_init(sid); if (!handle->pphd) break; /* Define un manejador de mensajes recibidos por la capa de presentacin. */ if (!modplcpp_notify((modplcpp_hd *) handle->pphd, __modplcap_procmsg__, handle)) break; /* Inicializa el buffer. */ handle->msgflag = 0; /* Inicializa el manejador de mensajes recibidos. */ handle->param = NULL; handle->recfun = NULL; /* Devuelve el manejador creado. */ return handle; } /* No se pudo inicializar la interfaz con la capa de aplicacin. */ modplcpp_release((modplcpp_hd *) handle->pphd); free(handle); return NULL; } /* Funcin modplcap_release: Libera los recursos utilizados por la capa de aplicacin del modem PLC. */ int modplcap_release(modplcap_hd *hd) { /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Libera el manejador de mensajes recibidos. */ modplcpp_notify((modplcpp_hd *) hd->pphd, NULL, NULL); /* Libera la interfaz con la capa de presentacin. */ modplcpp_release((modplcpp_hd *) hd->pphd); /* Libera los recursos utilizados por la capa de aplicacin. */ free(hd); /* xito. */ return 1; } /* Funcin modplcap_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ int modplcap_publish(modplcap_hd *hd, modplcap_grpid grpid) { /* Verifica que el manejador de la capa de aplicacin exista. */ if (!hd) return 0; /* Registra el dispositivo como publicador del grupo de difusin especificado. */ return modplcpp_publish((modplcpp_hd *) hd->pphd, grpid); } /* Funcin modplcap_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado.

332

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


*/ int modplcap_subscribe(modplcap_hd *hd, modplcap_grpid grpid) { /* Verifica que el manejador de la capa de aplicacin exista. */ if (!hd) return 0; /* Registra el dispositivo como suscriptor del grupo de difusin especificado. */ return modplcpp_subscribe((modplcpp_hd *) hd->pphd, grpid); } /* Funcin modplcap_leave: Desvincula el dispositivo del grupo de difusin especificado. */ int modplcap_leave(modplcap_hd *hd, modplcap_grpid grpid) { /* Verifica que el manejador de la capa de aplicacin exista. */ if (!hd) return 0; /* Desvincula el dispositivo del grupo de difusin especificado. */ return modplcpp_leave((modplcpp_hd *) hd->pphd, grpid); } /* Funcin modplcap_newmsg: Crea un nuevo mensaje. */ int modplcap_newmsg(modplcap_hd *hd, modplcap_msg *msg, modplcap_grpid grpid, modplcap_msgid msgid) { /* Verifica que el manejador de la capa de aplicacin exista. */ if (!hd) return 0; /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Inicializa el mensaje. */ msg->msgid = msgid; msg->msg = malloc(sizeof(modplcpp_msg)); if (!msg->msg) return 0; while(1) { if (msgid & 0x8000) { if (!modplcpp_newmsg((modplcpp_hd *) hd->pphd, (modplcpp_msg *) (msg->msg), grpid, MODPLCPP_NOSECMSG)) break; } else { if (!modplcpp_newmsg((modplcpp_hd *) hd->pphd, (modplcpp_msg *) (msg->msg), grpid, MODPLCPP_SECMSG)) break; } if (!modplcpp_putfield((modplcpp_msg *) (msg->msg), MODPLCPP_UINT16TYPE, 1, &msgid)) break; return 1; } free(msg->msg); msg->msg = NULL; return 0; } /* Funcin modplcap_copymsg: Crea un copia de un mensaje. */ int modplcap_copymsg(modplcap_msg *dest, modplcap_msg *src) {

FernandoArielBeunza79156

333

Tesis de Grado en Ingeniera Informtica


/* Verifica que el puntero al mensaje original no sea nulo. */ if (!src) return 0; /* Verifica que el puntero a la copia del mensaje no sea nulo. */ if (!dest) return 0; /* Copia el mensaje. */ dest->msgid = src->msgid; return modplcpp_copymsg((modplcpp_msg *) (dest->msg), (modplcpp_msg *) (src->msg)); } /* Funcin modplcap_putfield: Agrega un nuevo campo al mensaje. */ int modplcap_putfield(modplcap_msg *msg, modplcap_ftype type, unsigned char count, const void *dat) { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Agrega un nuevo campo al mensaje. */ return modplcpp_putfield((modplcpp_msg *) (msg->msg), type, count, dat); } /* Funcin modplcap_sendmsg: Enva un mensaje por medio de la capa de aplicacin. */ int modplcap_sendmsg(modplcap_msg *msg) { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Enva un mensaje. */ return modplcpp_sendmsg((modplcpp_msg *) (msg->msg)); } /* Funcin modplcap_receivemsg: Recibe un mensaje por medio de la capa de aplicacin. */ int modplcap_receivemsg(modplcap_hd *hd, modplcap_msg *msg) { /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Espera la llegada de un mensaje. */ while(!modplcap_poll(hd)); /* Recibe un mensaje. */ if (msg) { msg->msgid = hd->buffer.msgid; msg->msg = malloc(sizeof(modplcpp_msg)); if (!msg->msg) return 0; memcpy((modplcpp_msg *) (msg->msg), (modplcpp_msg *) (hd->buffer.msg), sizeof(modplcpp_msg)); } modplcpp_destroymsg(hd->buffer.msg); free(hd->buffer.msg); hd->msgflag = 0; return 1; } /* Funcin modplcap_getfield: Extrae un campo del mensaje. */ int modplcap_getfield(modplcap_msg *msg, modplcap_ftype *type,

334

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


unsigned char *count, void *dat) { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Extrae un campo del mensaje. */ return modplcpp_getfield((modplcpp_msg *) (msg->msg), type, count, dat); } /* Funcin modplcap_getgrpid: Devuelve el identificador de grupo del mensaje. */ modplcap_grpid modplcap_getgrpid(modplcap_msg *msg) { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Devuelve el identificador de grupo del mensaje. */ return ((modplcpp_msg *) (msg->msg))->grpid; } /* Funcin modplcap_getmsgid: Devuelve el identificador de mensaje. */ modplcap_msgid modplcap_getmsgid(modplcap_msg *msg) { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Devuelve el identificador de grupo del mensaje. */ return msg->msgid; } /* Funcin modplcap_destroymsg: Destruye un mensaje. */ int modplcap_destroymsg(modplcap_msg *msg) { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Destruye el mensaje. */ free(msg->msg); msg->msg = NULL; return 1; } /* Funcin modplcap_notify: Define una funcin manejadora de mensajes recibidos. */ int modplcap_notify(modplcap_hd *hd, void (*func)(modplcap_hd *, modplcap_msg *, void *), void *param) { /* Verifica que el manejador de la capa de aplicacin exista. */ if (!hd) return 0; /* Define un manejador de mensajes recibidos. */ hd->recfun = func; hd->param = param; return 1; } /* Funcin modplcap_poll: Verifica la llegada de un nuevo mensaje. */ int modplcap_poll(modplcap_hd *hd)

FernandoArielBeunza79156

335

Tesis de Grado en Ingeniera Informtica


{ /* Verifica que el manejador de la capa de aplicacin exista. */ if (!hd) return 0; /* Verifica la llegada de un nuevo mensaje. */ return (hd->msgflag != 0); } /* Funcin modplcap_status: Devuelve el estado del modem PLC. */ int modplcap_status(modplcap_hd *hd) { /* Verifica que el manejador de la capa de aplicacin exista. */ if (!hd) return 0; /* Devuelve el estado del modem PLC. */ return modplcpp_status(hd->pphd); }

/* Implementacin de funciones privadas. */ /* Funcin __modplcap_procmsg__: Procesa un mensaje recibido por medio de la capa de presentacin. */ static void __modplcap_procmsg__(modplcpp_hd *hd, modplcpp_msg *msg, void *param) { /* Variables. */ modplcpp_ftype type; /* Tipo de campo. */ modplcap_msgid msgid; /* Identificador de mensaje. */ unsigned char count; /* Contador. */ modplcap_hd *aphd; /* Manejador de capa de aplicacin. */

/* Carga el manejador de capa de aplicacin. */ aphd = (modplcap_hd *) param; /* Verifica si el buffer se encuentra lleno. */ if (aphd->msgflag) return; /* if if if Recibe el mensaje. */ (!modplcpp_getfield(msg, &type, &count, &msgid)) return; (type != MODPLCPP_UINT16TYPE) return; (count != 1) return;

/* Acepta el mensaje recibido. */ aphd->buffer.msgid = msgid; aphd->buffer.msg = malloc(sizeof(modplcpp_msg)); if (!aphd->buffer.msg) return; if (!modplcpp_copymsg((modplcpp_msg *) aphd->buffer.msg, msg)) return; aphd->msgflag = 1; /* Invoca a la funcin de atencin de recepcin de mensajes registrada. */ if (!aphd->recfun) return; aphd->recfun(aphd, &(aphd->buffer), aphd->param); modplcpp_destroymsg(aphd->buffer.msg); free(aphd->buffer.msg); aphd->msgflag = 0; }

336

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

C.3.2. Interfaz capa de enlace modplcdl.dll


En esta seccin se detalla el cdigo fuente de la biblioteca que implementa la interfaz con la capa de enlace del modem PLC, que se compone de los siguientes archivos:

Archivo config.h: en este archivo se definen parmetros de configuracin de la biblioteca dinmica que implementa la capa de enlace del modem PLC que no pueden ser modificados en tiempo de ejecucin. Archivo modplcdl.h: en este archivo se declaran las primitivas correspondientes al interfaz con la capa de enlace. Dichas primitivas brindan un conjunto de funcionalidades que permiten la comunicacin con la capa de enlace implementada en el modem PLC por medio del driver del mismo. Archivo modplcdl.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo modplcdl.h.

C.3.2.1. Archivo config.h


/* config.h Definicin de parmetros de configuracin. */

#if !defined(__CONFIG_H__) #define __CONFIG_H__

/* Interfaz con el driver del modem PLC. */ /* Cdigos de operaciones de la interfaz de la capa de enlace. */ #define MODDRVDL_CLOSE 0x00 #define MODDRVDL_OPEN 0x01 #define MODDRVDL_SEND 0x02 #define MODDRVDL_RECEIVE 0x03 #define MODDRVDL_POLL 0x04 #define MODDRVDL_GETADDRESS 0x05 #define MODDRVDL_ADDLOGADDRESS 0x06 #define MODDRVDL_DELLOGADDRESS 0x07 #define MODDRVDL_GETPHYADDRESS 0x08 #define MODDRVDL_STATUS 0x09 #define MODDRVDL_GETPAYLOADSIZE 0x0a

#endif

C.3.2.2. Archivo modplcdl.h


/* modplcdl.h: Declaracin de funciones referentes a la interfaz de la capa de enlace del modem PLC. */

#if !defined(__MODPLCDL_H__) #define __MODPLCDL_H__

FernandoArielBeunza79156

337

Tesis de Grado en Ingeniera Informtica

/* Archivos includos necesarios. */ #include <windows.h>

/* Definicin de tipos. */ /* Direccin fsica del modem PLC. */ typedef unsigned char modplcdl_phyaddr[8]; /* Direccin lgica del modem PLC. */ typedef unsigned long int modplcdl_logaddr; /* Manejador de interfaz con la capa de enlace del modem PLC. */ typedef struct { HANDLE hq; /* Manejador de cola de mensajes. */ HANDLE hm; /* Semforo de exclusin mtua. */ unsigned char sid; /* Identificador de interfaz de comunicacin por puerto serie. */ unsigned long int conncounter; /* Contador de conexiones abiertas. */ } modplcdl_hd; /* Manejador de conexin por medio de la capa de enlace del modem PLC. */ typedef struct { HANDLE hq; /* Manejador de cola de mensajes. */ HANDLE detectthread; /* Manejador de hilo de deteccin de recepcin. */ size_t payloadsize; /* Cantidad mxima de bytes que puede contener un mensaje. */ modplcdl_hd *dlhd; /* Manejador de interfaz con la capa de enlance del modem PLC. */ void (*recfun) (void *, modplcdl_phyaddr, void *, size_t, void *); /* Funcin manejadora de mensajes recibidos. */ void *param; /* Parmetros para la funcin manejadora de mensajes recibidos. */ } modplcdlconn_hd;

/* Declaracin de funciones pblicas. */ #if !defined(__MODPLCDL_DLL__) /* Funcin modplcdl_init: Inicializa los recursos utilizados por la capa de enlace del modem PLC. */ static modplcdl_hd * (*modplcdl_init)(int); /* Funcin modplcdl_release: Libera los recursos utilizados por la capa de enlace del modem PLC. */ static int (*modplcdl_release)(modplcdl_hd *); /* Funcin modplcdl_open: Abre una conexin por medio de la capa de enlace del modem PLC. */ static modplcdlconn_hd * (*modplcdl_open)(modplcdl_hd *, unsigned char, unsigned char);

338

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin modplcdl_close: Cierra una conexin por medio de la capa de enlace del modem PLC. */ static int (*modplcdl_close)(modplcdlconn_hd *); /* Funcin modplcdl_send: Enva un mensaje por medio de la capa de enlace del modem PLC. */ static size_t (*modplcdl_send)(modplcdlconn_hd *, modplcdl_phyaddr, unsigned char, const void *, size_t); /* Funcin modplcdl_receive: Recibe un mensaje por medio de la capa de enlace del modem PLC. */ static size_t (*modplcdl_receive)(modplcdlconn_hd *, modplcdl_phyaddr, void *, size_t); /* Funcin modplcdl_notify: Define una funcin manejadora de mensajes recibidos. */ static int (*modplcdl_notify)(modplcdlconn_hd *, void (*func)(void *, modplcdl_phyaddr, void *, size_t, void *), void *); /* Funcin modplcdl_poll: Verifica la recepcin de un mensaje. */ static int (*modplcdl_poll)(modplcdlconn_hd *); /* Funcin modplcdl_getaddress: Devuelve la direccin fsica de la capa de enlace del modem PLC. */ static int (*modplcdl_getaddress)(modplcdl_hd *, unsigned char, modplcdl_phyaddr); /* Funcin modplcdl_addlogaddress: Agrega una nueva direccin lgica a la capa de enlace del modem PLC. */ static int (*modplcdl_addlogaddress)(modplcdl_hd *, unsigned char, unsigned char, modplcdl_logaddr); /* Funcin modplcdl_dellogaddress: Elimina una direccin lgica a la capa de enlace del modem PLC. */ static int (*modplcdl_dellogaddress)(modplcdl_hd *, unsigned char, unsigned char, modplcdl_logaddr); /* Funcin modplcdl_getphyaddress: Devuelve la direccin fsica asociada a la direccin lgica de la capa de enlace del modem PLC. */ static int (*modplcdl_getphyaddress)(modplcdl_hd *hd, unsigned char, unsigned char, modplcdl_logaddr, modplcdl_phyaddr); /* Funcin modplcdl_status: Devuelve el estado del modem PLC. */ static int (*modplcdl_status)(modplcdl_hd *); /*

FernandoArielBeunza79156

339

Tesis de Grado en Ingeniera Informtica


Funcin modplcdl_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de enlace del modem PLC. */ static size_t (*modplcdl_getpayloadsize)(modplcdl_hd *, unsigned char);

/* Implementacin de funciones pblicas. */ /* Funcin modplcdl_loadlib: Carga la bliblioteca dinmica referente a la capa de enlace del modem PLC. */ static int modplcdl_loadlib(void) { /* Variables. */ struct HINSTANCE__ *hlib;

/* Manejador de biblioteca dinmica. */

/* Carga la biblioteca. */ hlib = NULL; modplcdl_init = NULL; modplcdl_release = NULL; modplcdl_open = NULL; modplcdl_close = NULL; modplcdl_send = NULL; modplcdl_receive = NULL; modplcdl_notify = NULL; modplcdl_poll = NULL; modplcdl_getaddress = NULL; modplcdl_addlogaddress = NULL; modplcdl_dellogaddress = NULL; modplcdl_getphyaddress = NULL; modplcdl_status = NULL; modplcdl_getpayloadsize = NULL; hlib = LoadLibrary("MODPLCDL"); if (!hlib) return 0; modplcdl_init = (modplcdl_hd * (*)(int)) GetProcAddress(hlib, "modplcdl_init"); modplcdl_release = (int (*)(modplcdl_hd *)) GetProcAddress(hlib, "modplcdl_release"); modplcdl_open = (modplcdlconn_hd * (*)(modplcdl_hd *, unsigned char, unsigned char)) GetProcAddress(hlib, "modplcdl_open"); modplcdl_close = (int (*)(modplcdlconn_hd *)) GetProcAddress(hlib, "modplcdl_close"); modplcdl_send = (size_t (*)(modplcdlconn_hd *, modplcdl_phyaddr, unsigned char, const void *, size_t)) GetProcAddress(hlib, "modplcdl_send"); modplcdl_receive = (size_t (*)(modplcdlconn_hd *, modplcdl_phyaddr, void *, size_t)) GetProcAddress(hlib, "modplcdl_receive"); modplcdl_notify = (int (*)(modplcdlconn_hd *, void (*func)(void *, modplcdl_phyaddr, void *, size_t, void *), void *)) GetProcAddress(hlib, "modplcdl_notify"); modplcdl_poll = (int (*)(modplcdlconn_hd *)) GetProcAddress(hlib, "modplcdl_poll"); modplcdl_getaddress = (int (*)(modplcdl_hd *, unsigned char, modplcdl_phyaddr)) GetProcAddress(hlib, "modplcdl_getaddress"); modplcdl_addlogaddress = (int (*)(modplcdl_hd *, unsigned char, unsigned char, modplcdl_logaddr)) GetProcAddress(hlib, "modplcdl_addlogaddress"); modplcdl_dellogaddress = (int (*)(modplcdl_hd *, unsigned char, unsigned char, modplcdl_logaddr)) GetProcAddress(hlib, "modplcdl_dellogaddress"); modplcdl_getphyaddress = (int (*)(modplcdl_hd *hd, unsigned char, unsigned char, modplcdl_logaddr, modplcdl_phyaddr))

340

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


GetProcAddress(hlib, "modplcdl_getphyaddress"); modplcdl_status = (int (*)(modplcdl_hd *)) GetProcAddress(hlib, "modplcdl_status"); modplcdl_getpayloadsize = (size_t (*)(modplcdl_hd *, unsigned char)) GetProcAddress(hlib, "modplcdl_getpayloadsize"); /* Verifica que todas las funciones de la biblioteca se hayan cargado. */ if ((!modplcdl_init) || (!modplcdl_release) || (!modplcdl_open) || (!modplcdl_close) || (!modplcdl_send) || (!modplcdl_receive) || (!modplcdl_notify) || (!modplcdl_poll) || (!modplcdl_getaddress) || (!modplcdl_addlogaddress) || (!modplcdl_dellogaddress) || (!modplcdl_getphyaddress) || (!modplcdl_status) || (!modplcdl_getpayloadsize)) return 0; /* xito. */ return 1; } #endif

#endif

C.3.2.3. Archivo modplcdl.c


/* modplcdl.c: Implementacin de funciones referentes a la interfaz de la capa de enlace del modem PLC. */

/* Archivos includos necesarios. */ #define __MODPLCDL_DLL__ #include "config.h" #include <stdio.h> #include <windows.h> #include <process.h> #include "modplcdl.h"

/* Declaracin de funciones pblicas. */ modplcdl_hd *modplcdl_init(int); int modplcdl_release(modplcdl_hd *); modplcdlconn_hd *modplcdl_open(modplcdl_hd *, unsigned char, unsigned char); int modplcdl_release(modplcdl_hd *); size_t modplcdl_send(modplcdlconn_hd *, modplcdl_phyaddr, unsigned char, const void *, size_t); size_t modplcdl_receive(modplcdlconn_hd *, modplcdl_phyaddr, void *, size_t); int modplcdl_notify(modplcdlconn_hd *, void (*func)(void *, modplcdl_phyaddr, void *, size_t, void *), void *); int modplcdl_poll(modplcdlconn_hd *); int modplcdl_getaddress(modplcdl_hd *, unsigned char, modplcdl_phyaddr); int modplcdl_addlogaddress(modplcdl_hd *, unsigned char, unsigned char, modplcdl_logaddr); int modplcdl_dellogaddress(modplcdl_hd *, unsigned char, unsigned char, modplcdl_logaddr); int modplcdl_getphyaddress(modplcdl_hd *hd, unsigned char, unsigned char, modplcdl_logaddr, modplcdl_phyaddr); int modplcdl_status(modplcdl_hd *); size_t modplcdl_getpayloadsize(modplcdl_hd *, unsigned char);

/* Declaracin de funciones privadas. */ static DWORD WINAPI __modplcdl_detectproc__(LPVOID); static int __modplcdl_sendrecv__(HANDLE, void *, size_t, const void *, size_t);

FernandoArielBeunza79156

341

Tesis de Grado en Ingeniera Informtica


/* Implementacin de funciones pblicas. */ /* Funcin modplcdl_init: Inicializa los recursos utilizados por la capa de enlace del modem PLC. */ modplcdl_hd *modplcdl_init(int sid) { /* Variables. */ int layer; int result; modplcdl_hd *handle; char qname[256];

/* Capa a la que se quiere accerder. */ /* Resultado de la solicitud. */ /* Manejador de interfaz con la capa de enlace del modem PLC. */ /* Nombre de la cola de mensajes. */

/* Crea un nuevo manejador de interfaz con la capa de enlace del modem PLC. */ handle = (modplcdl_hd *) malloc(sizeof(modplcdl_hd)); if (!handle) return NULL; /* Inicializa el manejador de interfaz con la capa de enlace del modem PLC. */ while(1) { /* Abre una conexin con la cola de mensajes del driver del modem PLC. */ sprintf(qname, "\\\\.\\pipe\\modemplc%i", sid); handle->hq = CreateFile(qname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (handle->hq == INVALID_HANDLE_VALUE) break; /* Inicializa semforo de exclusin mtua. */ handle->hm = CreateSemaphore(NULL, 1, 1, NULL); if (handle->hm == INVALID_HANDLE_VALUE) break; /* Solicita acceder a la capa de enlace del modem PLC. */ layer = 2; if (!__modplcdl_sendrecv__(handle->hq, &result, sizeof(result), &layer, sizeof(layer))) break; if (!result) break; /* Almacena la interfaz de comunicacin por puerto serie. */ handle->sid = sid; /* Inicializa el contador de conexiones abiertas. */ handle->conncounter = 0; /* Devuelve el manejador creado. */ return handle; } /* No se pudo inicializar la interfaz con la capa de enlace del modem PLC. */ CloseHandle(handle->hm); CloseHandle(handle->hq); free(handle); return NULL; } /* Funcin modplcdl_release: Libera los recursos utilizados por la capa de enlace del modem PLC. */ int modplcdl_release(modplcdl_hd *hd) { /* Variables. */

342

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


int op; int result; /* Identificador de operacin. */ /* Resultado de la solicitud. */

/* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Verifica que no existan conexiones abiertas. */ if (hd->conncounter) return 0; /* Solicita el cierre de la conexin. */ op = MODDRVDL_CLOSE; if (!__modplcdl_sendrecv__(hd->hq, &result, sizeof(result), &op, sizeof(op))) return 0; if (!result) return 0; /* Libera los recursos utilizados por la interfaz con la capa de enlace del modem PLC. */ CloseHandle(hd->hq); CloseHandle(hd->hm); free(hd); /* xito. */ return 1; } /* Funcin modplcdl_open: Abre una conexin por medio de la capa de enlace del modem PLC. */ modplcdlconn_hd *modplcdl_open(modplcdl_hd *hd, unsigned char iface, unsigned char prot) { /* Variables. */ int op; /* Identificador de operacin. */ int layer; /* Capa a la que se quiere accerder. */ int result; /* Resultado de la solicitud. */ size_t payloadsize; /* Cantidad de bytes que puede contener un mensaje. */ modplcdlconn_hd *handle; /* Manejador de conexin de la capa de enlace del modem PLC. */ char qname[256]; /* Nombre de la cola de mensajes. */

/* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return NULL; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Crea un nuevo manejador de conexin por medio de la capa de enlace del modem PLC. */ handle = (modplcdlconn_hd *) malloc(sizeof(modplcdlconn_hd)); if (!handle) { ReleaseSemaphore(hd->hm, 1, NULL); return NULL; } /* Inicializa el manejador de conexin. */ while(1) { /* Carga el manejador de interfaz con la capa de enlace del modem PLC. */ handle->dlhd = hd;

FernandoArielBeunza79156

343

Tesis de Grado en Ingeniera Informtica


/* Abre una conexin con la cola de mensajes del driver del modem PLC. */ sprintf(qname, "\\\\.\\pipe\\modemplc%i", hd->sid); handle->hq = CreateFile(qname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (handle->hq == INVALID_HANDLE_VALUE) break; /* Solicita acceder a la capa de enlace del modem PLC. */ layer = 2; if (!__modplcdl_sendrecv__(handle->hq, &result, sizeof(result), &layer, sizeof(layer))) break; if (!result) break; /* Solicita abrir una conexin. */ op = MODDRVDL_OPEN; if (!__modplcdl_sendrecv__(handle->hq, NULL, 0, &op, sizeof(op))) break; if (!__modplcdl_sendrecv__(handle->hq, NULL, 0, &iface, sizeof(iface))) break; if (!__modplcdl_sendrecv__(handle->hq, &result, sizeof(result), &prot, sizeof(prot))) break; if (!result) break; /* Solicita la cantidad mxima de bytes que puede contener un mensaje. */ op = MODDRVDL_GETPAYLOADSIZE; if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ if (!__modplcdl_sendrecv__(hd->hq, &payloadsize, sizeof(payloadsize), &iface, sizeof(iface))) break; if (!payloadsize) break; handle->payloadsize = payloadsize; /* Inicializa el manejador de mensajes recibidos. */ handle->param = NULL; handle->recfun = NULL; /* Actualiza el nmero de conexiones. */ handle->dlhd->conncounter ++; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve el manejador creado. */ return handle; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* No se pudo abrir la conexin. */ CloseHandle(handle->hq); free(handle); return NULL; } /* Funcin modplcdl_close: Cierra una conexin por medio de la capa de enlace del modem PLC. */ int modplcdl_close(modplcdlconn_hd *hd) { /* Variables. */ int op; int result;

/* Identificador de operacin. */ /* Resultado de la solicitud. */

344

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Libera el manejador de mensajes recibidos. */ modplcdl_notify(hd, NULL, NULL); /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->dlhd->hm, INFINITE); /* Solicita el cierre de la conexin. */ op = MODDRVDL_CLOSE; if (!__modplcdl_sendrecv__(hd->hq, &result, sizeof(result), &op, sizeof(op))) return 0; if (!result) return 0; /* Actualiza el nmero de conexiones. */ hd->dlhd->conncounter --; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->dlhd->hm, 1, NULL); /* Libera los recursos utilizados por la conexin por medio de la capa de enlace del modem PLC. */ CloseHandle(hd->hq); free(hd); /* xito. */ return 1; } /* Funcin modplcdl_send: Enva un mensaje por medio de la capa de enlace del modem PLC. */ size_t modplcdl_send(modplcdlconn_hd *hd, modplcdl_phyaddr addr, unsigned char prio, const void *msg, size_t msgsize) { /* Variables. */ int op; /* Identificador de operacin. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->dlhd->hm, INFINITE); /* Enva un mensaje. */ while(1) { /* Solicita el envo de un mensaje. */ op = MODDRVDL_SEND; if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva la direccin destinataria. */ if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, addr, sizeof(modplcdl_phyaddr))) break; /* Enva la prioridad del mensaje. */ if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &prio, sizeof(prio))) break; /* Enva el tamao del mensaje. */ if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &msgsize, sizeof(msgsize))) break;

FernandoArielBeunza79156

345

Tesis de Grado en Ingeniera Informtica


/* Enva el mensaje. */ if (!__modplcdl_sendrecv__(hd->hq, &msgsize, sizeof(msgsize), msg, msgsize)) break; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->dlhd->hm, 1, NULL); /* Devuelve la cantidad de bytes enviados. */ return msgsize; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->dlhd->hm, 1, NULL); /* No se pudo realizar el envo. */ return 0; } /* Funcin modplcdl_receive: Recibe un mensaje por medio de la capa de enlace del modem PLC. */ size_t modplcdl_receive(modplcdlconn_hd *hd, modplcdl_phyaddr addr, void *msg, size_t msgsize) { /* Variables. */ int op; /* Identificador de operacin. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->dlhd->hm, INFINITE); /* Recibe while(1) { /* op if un mensaje. */

Solicita la recepcin de un mensaje. */ = MODDRVDL_RECEIVE; (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break;

/* Enva la cantidad de bytes que se solicita recibir del mensaje. */ if (!__modplcdl_sendrecv__(hd->hq, &msgsize, sizeof(msgsize), &msgsize, sizeof(msgsize))) break; if (!msgsize) break; /* Recibe la direccin de origen del mensaje. */ if (!__modplcdl_sendrecv__(hd->hq, addr, sizeof(modplcdl_phyaddr), NULL, 0)) break; /* Recibe el mensaje. */ if (!__modplcdl_sendrecv__(hd->hq, msg, msgsize, NULL, 0)) break; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->dlhd->hm, 1, NULL); /* Devuelve la cantidad de bytes enviados. */ return msgsize; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->dlhd->hm, 1, NULL); /* No se pudo realizar la recepcin. */

346

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


return 0; } /* Funcin modplcdl_notify: Define una funcin manejadora de mensajes recibidos. */ int modplcdl_notify(modplcdlconn_hd *hd, void (*func)(void *, modplcdl_phyaddr, void *, size_t, void *), void *param) { /* Variables. */ DWORD tid; /* Identificador de hilo. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Si la funcin manejadora es nula y no hay ninguna funcin manejadora definida previamente no se hace nada. */ if ((!func) && (!hd->recfun)) return 1; /* Si la funcin manejadora no es nula y hay una funcin manejadora previamente definida actualiza la funcin manejadora. */ if ((func) && (hd->recfun)) { WaitForSingleObject(hd->dlhd->hm, INFINITE); hd->recfun = func; hd->param = param; ReleaseSemaphore(hd->dlhd->hm, 1, NULL); return 1; } /* Si la funcin manejadora es nula y hay una funcin manejadora definida previamente se elimina esta ltima. */ if ((!func) && (hd->recfun)) { WaitForSingleObject(hd->dlhd->hm, INFINITE); hd->recfun = NULL; hd->param = param; ReleaseSemaphore(hd->dlhd->hm, 1, NULL); WaitForSingleObject(hd->detectthread, INFINITE); return 1; } /* Si la funcin manejadora no es nula y no hay una funcin manejadora previamente definida se define la nueva funcin manejadora. */ if ((func) && (!hd->recfun)) { WaitForSingleObject(hd->dlhd->hm, INFINITE); hd->recfun = func; hd->param = param; hd->detectthread = CreateThread(NULL, 0, __modplcdl_detectproc__, hd, 0, &tid); if (hd->detectthread == INVALID_HANDLE_VALUE) { hd->recfun = NULL; hd->param = NULL; ReleaseSemaphore(hd->dlhd->hm, 1, NULL); return 0; } ReleaseSemaphore(hd->dlhd->hm, 1, NULL); return 1; } /* No se pudo definir la funcin manejadora de mensajes recibidos. */ return 0; } /* Funcin modplcdl_poll:

FernandoArielBeunza79156

347

Tesis de Grado en Ingeniera Informtica


Verifica la recepcin de un mensaje. */ int modplcdl_poll(modplcdlconn_hd *hd) { /* Variables. */ int op; int result;

/* Identificador de operacin. */ /* Resultado de la operacin. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->dlhd->hm, INFINITE); /* Solicita verificar la recepcin de un mensaje. */ op = MODDRVDL_POLL; if (!__modplcdl_sendrecv__(hd->hq, &result, sizeof(result), &op, sizeof(op))) result = 0; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->dlhd->hm, 1, NULL); /* Devuelve el resultado de la solicitud. */ return result; } /* Funcin modplcdl_getaddress: Devuelve la direccin fsica de la capa de enlace del modem PLC. */ int modplcdl_getaddress(modplcdl_hd *hd, unsigned char iface, modplcdl_phyaddr addr) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Obtiene la direccin fsica del modem PLC. */ result = 0; while(1) { /* Solicita la direccin fsica del modem PLC. */ op = MODDRVDL_GETADDRESS; if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva el identifcador de interfaz fsica. */ if (!__modplcdl_sendrecv__(hd->hq, &result, sizeof(result), &iface, sizeof(iface))) break; if (!result) break; /* Recibe la direccin fsica. */ if (!__modplcdl_sendrecv__(hd->hq, addr, sizeof(modplcdl_phyaddr), NULL, 0)) result = 0; break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL);

348

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Devuelve el resultado de la solicitud. */ return result; } /* Funcin modplcdl_addlogaddress: Agrega una nueva direccin lgica a la capa de enlace del modem PLC. */ int modplcdl_addlogaddress(modplcdl_hd *hd, unsigned char iface, unsigned char prot, modplcdl_logaddr addr) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Agrega una direccin lgica. */ result = 0; while(1) { /* Solicita agregar una direccin lgica. */ op = MODDRVDL_ADDLOGADDRESS; if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &iface, sizeof(iface))) break; /* Enva el identificador de protocolo. */ if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &prot, sizeof(prot))) break; /* Enva la direccin lgica. */ __modplcdl_sendrecv__(hd->hq, &result, sizeof(result), &addr, sizeof(addr)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve el resultado de la solicitud. */ return result; } /* Funcin modplcdl_dellogaddress: Elimina una direccin lgica a la capa de enlace del modem PLC. */ int modplcdl_dellogaddress(modplcdl_hd *hd, unsigned char iface, unsigned char prot, modplcdl_logaddr addr) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE);

FernandoArielBeunza79156

349

Tesis de Grado en Ingeniera Informtica


/* Elimina una direccin lgica. */ result = 0; while(1) { /* Solicita la eliminacin de una direccin lgica. */ op = MODDRVDL_DELLOGADDRESS; if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &iface, sizeof(iface))) break; /* Enva el identificador de protocolo. */ if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &prot, sizeof(prot))) break; /* Enva la direccin lgica. */ __modplcdl_sendrecv__(hd->hq, &result, sizeof(result), &addr, sizeof(addr)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve el resultado de la solicitud. */ return result; } /* Funcin modplcdl_getphyaddress: Devuelve la direccin fsica asociada a la direccin lgica de la capa de enlace del modem PLC. */ int modplcdl_getphyaddress(modplcdl_hd *hd, unsigned char iface, unsigned char prot, modplcdl_logaddr laddr, modplcdl_phyaddr paddr) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Obtiene la direccin fsica asociada a la direccin lgica. */ result = 0; while(1) { /* Solicita la direccin fsica. */ op = MODDRVDL_GETPHYADDRESS; if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &iface, sizeof(iface))) break; /* Enva el identificador de protocolo. */ if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &prot, sizeof(prot))) break; /* Enva la direccin lgica. */ if (!__modplcdl_sendrecv__(hd->hq, &result, sizeof(result), &laddr, sizeof(laddr))) break;

350

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


if (!result) break; /* Recibe la direccin fsica. */ __modplcdl_sendrecv__(hd->hq, paddr, sizeof(modplcdl_phyaddr), NULL, 0); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve el resultado de la solicitud. */ return result; } /* Funcin modplcdl_status: Devuelve el estado del modem PLC. */ int modplcdl_status(modplcdl_hd *hd) { /* Variables. */ int op; int result;

/* Identificador de operacin. */ /* Resultado de la operacin. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Obtiene el estado del modem PLC. */ op = MODDRVDL_STATUS; if (!__modplcdl_sendrecv__(hd->hq, &result, sizeof(result), &op, sizeof(op))) result = 0; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve el estado del modem PLC. */ return result; } /* Funcin modplcdl_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de enlace del modem PLC. */ size_t modplcdl_getpayloadsize(modplcdl_hd *hd, unsigned char iface) { /* Variables. */ int op; /* Operacin. */ size_t payloadsize; /* Cantidad de bytes que puede contener un mensaje. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ payloadsize = 0; while(1) { /* Solicita la cantidad mxima de bytes que puede contener un

FernandoArielBeunza79156

351

Tesis de Grado en Ingeniera Informtica


mensaje. */ op = MODDRVDL_GETPAYLOADSIZE; if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ __modplcdl_sendrecv__(hd->hq, &payloadsize, sizeof(payloadsize), &iface, sizeof(iface)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve la cantidad mxima de bytes que puede contener un mensaje. */ return payloadsize; }

/* Implementacin de funciones privadas. */ /* Funcin __modplcdl_detectproc__: Verifica la existencia de un mensaje recibido disponible para ser ledo. */ static DWORD WINAPI __modplcdl_detectproc__(LPVOID param) { /* Variables. */ int op; int result; int captureflag; size_t msgsize; modplcdl_phyaddr addr; modplcdlconn_hd *hd;

/* Identificador de operacin. */ /* Resultado de la operacin. */ /* Indicador de captura de un mensaje. */ /* Tamao del mensaje. */ /* Direccin de origen. */ /* Manejador de conexin por medio de la capa de enlace del modem PLC. */

void (*func) (void *, modplcdl_phyaddr, void *, size_t, void *); unsigned char *msg;

/* Funcin manejadora de mensajes recibidos. */ /* Puntero al mensaje recibido. */

/* Carga el manejador de interfaz con la capa de enlace del modem PLC. */ hd = (modplcdlconn_hd *) param; /* Verifica la existencia de un mensaje recibido. */ while(1) { /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->dlhd->hm, INFINITE); /* Verifica la recepcin de un mensaje. */ func = hd->recfun; if (!func) break; op = MODDRVDL_POLL; if (__modplcdl_sendrecv__(hd->hq, &result, sizeof(result), &op, sizeof(op))) captureflag = result; /* Recibe el mensaje. */ while(captureflag) { /* Solicita la recepcin de un mensaje. */ op = MODDRVDL_RECEIVE; if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva la cantidad de bytes que se solicita recibir del

352

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


mensaje. */ msgsize = hd->payloadsize; if (!__modplcdl_sendrecv__(hd->hq, &msgsize, sizeof(msgsize), &msgsize, sizeof(msgsize))) break; if (!msgsize) break; /* Recibe la direccin de origen del mensaje. */ if (!__modplcdl_sendrecv__(hd->hq, addr, sizeof(modplcdl_phyaddr), NULL, 0)) break; /* Recibe el mensaje. */ msg = (unsigned char *) malloc(msgsize * sizeof(unsigned char)); if (!msg) { captureflag = 0; break; } __modplcdl_sendrecv__(hd->hq, msg, msgsize, NULL, 0); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->dlhd->hm, 1, NULL); /* Verifica si se ha detectado la recepcin de un mensaje para invocar al manejador de mensajes recibidos. */ if (captureflag) { func(hd, addr, msg, msgsize, hd->param); free(msg); } } /* Fin de ejecucin del hilo de deteccin de recepcin. */ ReleaseSemaphore(hd->dlhd->hm, 1, NULL); return 0; } /* Funcin __modplcdl_sendrecv__: Intercambia datos con el driver del modem PLC. */ static int __modplcdl_sendrecv__(HANDLE hq, void *outdata, size_t outsize, const void *indata, size_t insize) { /* Variables. */ size_t last; /* Cantidad de bytes enviados o recibidos. */ size_t sent; /* Cantidad de bytes enviados. */ size_t received; /* Cantidad de bytes recibidos. */

/* Verifica que el manejador de cola de mensajes exista. */ if (hq == INVALID_HANDLE_VALUE) return 0; /* Enva la operacin. */ sent = 0; while((indata) && (sent < insize)) { if (!WriteFile(hq, indata, insize, &last, NULL)) return 0; sent += last; } /* Recibe la respuesta. */ received = 0; while((outdata) && (received < outsize)) { if (!ReadFile(hq, outdata, outsize, &last, NULL)) return 0;

FernandoArielBeunza79156

353

Tesis de Grado en Ingeniera Informtica


received += last; } /* xito. */ return 1; }

C.3.3. Interfaz capa fsica modplcphy.dll


En esta seccin se detalla el cdigo fuente de la biblioteca que implementa la interfaz con la capa fsica del modem PLC, que se compone de los siguientes archivos:

Archivo config.h: en este archivo se definen parmetros de configuracin de la biblioteca dinmica que implementa la interfaz con la capa fsica del modem PLC que no pueden ser modificados en tiempo de ejecucin. Archivo modplcphy.h: en este archivo se declaran las primitivas correspondientes al interfaz con la capa fsica. Dichas primitivas brindan un conjunto de funcionalidades que permiten la comunicacin con la capa fsica implementada en el modem PLC por medio del driver del mismo. Archivo modplcphy.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo modplcphy.h.

C.3.3.1. Archivo config.h


/* config.h Definicin de parmetros de configuracin. */

#if !defined(__CONFIG_H__) #define __CONFIG_H__

/* Interfaz con el driver del modem PLC. */ /* Cdigos de operaciones de la interfaz de la capa fsica. */ #define MODDRVPHY_RELEASE 0x00 #define MODDRVPHY_SNDFRAME 0x01 #define MODDRVPHY_CAPFRAME 0x02 #define MODDRVPHY_GETFRAME 0x03 #define MODDRVPHY_POLL 0x04 #define MODDRVPHY_RSDFRAME 0x05 #define MODDRVPHY_CLRBUFFER 0x06 #define MODDRVPHY_SENSECHANNEL 0x07 #define MODDRVPHY_GENSIGNAL 0x08 #define MODDRVPHY_TSTRECEIVE 0x09 #define MODDRVPHY_STATUS 0x0a #define MODDRVPHY_GETPAYLOADSIZE 0x0b

#endif

354

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

C.3.3.2. Archivo modplcphy.h


/* modplcphy.h: Declaracin de funciones referentes a la interfaz de la capa fsica del modem PLC. */

#if !defined(__MODPLCPHY_H__) #define __MODPLCPHY_H__

/* Archivos includos necesarios. */ #include <windows.h>

/* Definicin de tipos. */ /* Manejador de interfaz con la capa fsica del modem PLC. */ typedef struct { HANDLE hq; /* Manejador de cola de mensajes. */ HANDLE hm; /* Semforo de exclusin mtua. */ struct { DWORD threadid; /* Identificador de hilo de deteccin. */ HANDLE detectthread; /* Manejador de hilo de deteccin de recepcin. */ void (*recfun)(void *, void *); /* Funcin manejadora de tramas capturadas. */ void *param; /* Parmetros para la funcin manejadora de tramas recibidas. */ } iface[256]; /* Tabla de interfaces fsicas. */ } modplcphy_hd;

/* Definicin de constantes. */ /* Tipos de seales. */ #define MODPLCPHY_NOISESIGNAL #define MODPLCPHY_TESTSIGNAL1 #define MODPLCPHY_TESTSIGNAL2

0x01 0x02 0x03

/* Declaracin de funciones pblicas. */ #if !defined(__MODPLCPHY_DLL__) /* Funcin modplcphy_init: Inicializa los recursos utilizados por la capa fsica del modem PLC. */ static modplcphy_hd * (*modplcphy_init)(int); /* Funcin modplcphy_release: Libera los recursos utilizados por la capa fsica del modem PLC. */ static int (*modplcphy_release)(modplcphy_hd *); /* Funcin modplcphy_sndframe: Enva una trama. */ static size_t (*modplcphy_sndframe)(modplcphy_hd *, unsigned char, const void *, size_t);

FernandoArielBeunza79156

355

Tesis de Grado en Ingeniera Informtica


/* Funcin modplcphy_capframe: Captura una trama. */ static int (*modplcphy_capframe)(modplcphy_hd *, unsigned char, size_t); /* Funcin modplcphy_getframe: Obtiene una trama capturada previamente. */ static size_t (*modplcphy_getframe)(modplcphy_hd *, unsigned char, void *, size_t); /* Funcin modplcphy_notify: Define una funcin manejadora de tramas capturadas. */ static int (*modplcphy_notify)(modplcphy_hd *, unsigned char, void (*func)(modplcphy_hd *, void *), void *); /* Funcin modplcphy_poll: Verifica la captura de una trama. */ static int (*modplcphy_poll)(modplcphy_hd *, unsigned char); /* Funcin modplcphy_rsdframe: Reenva una trama. */ static int (*modplcphy_rsdframe)(modplcphy_hd *, unsigned char); /* Funcin modplcphy_clrbuffer: Limpia el buffer de captura de tramas. */ static int (*modplcphy_clrbuffer)(modplcphy_hd *, unsigned char); /* Funcin modplcphy_sensechannel: Sensa el estado del canal de comunicacin. */ static int (*modplcphy_sensechannel)(modplcphy_hd *, unsigned char, unsigned char, long int); /* Funcin modplcphy_gensignal: Genera la seal especificada por medio de la capa fsica del modem PLC. */ static int (*modplcphy_gensignal)(modplcphy_hd *, unsigned char, int); /* Funcin modplcphy_tstreceive: Realiza una prueba de recepcin. */ static int (*modplcphy_tstreceive)(modplcphy_hd *, unsigned char); /* Funcin modplcphy_status: Devuelve el estado del modem PLC. */ static int (*modplcphy_status)(modplcphy_hd *); /* Funcin modplcphy_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener una trama de la capa fsica del modem PLC. */ static size_t (*modplcphy_getpayloadsize)(modplcphy_hd *, unsigned char);

356

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Implementacin de funciones pblicas. */ /* Funcin modplcphy_loadlib: Carga la bliblioteca dinmica referente a la capa fsica del modem PLC. */ static int modplcphy_loadlib(void) { /* Variables. */ struct HINSTANCE__ *hlib;

/* Manejador de biblioteca dinmica. */

/* Carga la biblioteca. */ hlib = NULL; modplcphy_init = NULL; modplcphy_release = NULL; modplcphy_sndframe = NULL; modplcphy_capframe = NULL; modplcphy_getframe = NULL; modplcphy_notify = NULL; modplcphy_poll = NULL; modplcphy_rsdframe = NULL; modplcphy_clrbuffer = NULL; modplcphy_sensechannel = NULL; modplcphy_gensignal = NULL; modplcphy_tstreceive = NULL; modplcphy_status = NULL; modplcphy_getpayloadsize = NULL; hlib = LoadLibrary("MODPLCPHY"); if (!hlib) return 0; modplcphy_init = (modplcphy_hd * (*)(int)) GetProcAddress(hlib, "modplcphy_init"); modplcphy_release = (int (*)(modplcphy_hd *)) GetProcAddress(hlib, "modplcphy_release"); modplcphy_sndframe = (size_t (*)(modplcphy_hd *, unsigned char, const void *, size_t)) GetProcAddress(hlib, "modplcphy_sndframe"); modplcphy_capframe = (int (*)(modplcphy_hd *, unsigned char, size_t)) GetProcAddress(hlib, "modplcphy_capframe"); modplcphy_getframe = (size_t (*)(modplcphy_hd *, unsigned char, void *, size_t)) GetProcAddress(hlib, "modplcphy_getframe"); modplcphy_notify = (int (*)(modplcphy_hd *, unsigned char, void (*func)(modplcphy_hd *, void *), void *)) GetProcAddress(hlib, "modplcphy_notify"); modplcphy_poll = (int (*)(modplcphy_hd *, unsigned char)) GetProcAddress(hlib, "modplcphy_poll"); modplcphy_rsdframe = (int (*)(modplcphy_hd *, unsigned char)) GetProcAddress(hlib, "modplcphy_rsdframe"); modplcphy_clrbuffer = (int (*)(modplcphy_hd *, unsigned char)) GetProcAddress(hlib, "modplcphy_clrbuffer"); modplcphy_sensechannel = (int (*)(modplcphy_hd *, unsigned char, unsigned char, long int)) GetProcAddress(hlib, "modplcphy_sensechannel"); modplcphy_gensignal = (int (*)(modplcphy_hd *, unsigned char, int)) GetProcAddress(hlib, "modplcphy_gensignal"); modplcphy_tstreceive = (int (*)(modplcphy_hd *, unsigned char)) GetProcAddress(hlib, "modplcphy_tstreceive"); modplcphy_status = (int (*)(modplcphy_hd *)) GetProcAddress(hlib, "modplcphy_status"); modplcphy_getpayloadsize = (size_t (*)(modplcphy_hd *, unsigned char)) GetProcAddress(hlib, "modplcphy_getpayloadsize"); /* Verifica que todas las funciones de la biblioteca se hayan cargado. */ if ((!modplcphy_init) || (!modplcphy_release) || (!modplcphy_sndframe) || (!modplcphy_capframe) || (!modplcphy_getframe) || (!modplcphy_notify) || (!modplcphy_poll) || (!modplcphy_rsdframe) || (!modplcphy_clrbuffer) || (!modplcphy_sensechannel) || (!modplcphy_gensignal) || (!modplcphy_tstreceive) ||

FernandoArielBeunza79156

357

Tesis de Grado en Ingeniera Informtica


(!modplcphy_status) || (!modplcphy_getpayloadsize)) return 0; /* xito. */ return 1; } #endif

#endif

C.3.3.3. Archivo modplcphy.c


/* modplcphy.c: Implementacin de funciones referentes a la interfaz de la capa fsica del modem PLC. */

/* Archivos includos necesarios. */ #define __MODPLCPHY_DLL__ #include "config.h" #include <stdio.h> #include <windows.h> #include <process.h> #include "modplcphy.h"

/* Declaracin de funciones pblicas. */ modplcphy_hd *__modplcphy_init__(int); int modplcphy_release(modplcphy_hd *); size_t modplcphy_sndframe(modplcphy_hd *, unsigned char, const void *, size_t); int modplcphy_capframe(modplcphy_hd *, unsigned char, size_t); size_t modplcphy_getframe(modplcphy_hd *, unsigned char, void *, size_t); int modplcphy_notify(modplcphy_hd *, unsigned char, void (*func)(modplcphy_hd *, void *), void *); int modplcphy_poll(modplcphy_hd *, unsigned char); int modplcphy_rsdframe(modplcphy_hd *, unsigned char); int modplcphy_clrbuffer(modplcphy_hd *, unsigned char); int modplcphy_sensechannel(modplcphy_hd *, unsigned char, unsigned char, long int); int modplcphy_gensignal(modplcphy_hd *, unsigned char, int); int modplcphy_tstreceive(modplcphy_hd *, unsigned char); int modplcphy_status(modplcphy_hd *); size_t modplcphy_getpayloadsize(modplcphy_hd *, unsigned char);

/* Declaracin de funciones privadas. */ static DWORD WINAPI __modplcphy_detectproc__(LPVOID); static int __modplcphy_sendrecv__(modplcphy_hd *, void *, size_t, const void *, size_t);

/* Implementacin de funciones pblicas. */ /* Funcin modplcphy_init: Inicializa los recursos utilizados por la capa fsica del modem PLC. */ modplcphy_hd *modplcphy_init(int sid) { /* Variables. */ int layer; int result; short int iface;

/* Capa a la que se quiere accerder. */ /* Resultado de la solicitud. */ /* Identificadores de interfaces

358

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


modplcphy_hd *handle; char qname[256]; fsicas. */ /* Manejador de interfaz con la capa fsica del modem PLC. */ /* Nombre de la cola de mensajes. */

/* Crea un nuevo manejador de interfaz con la capa fsica del modem PLC. */ handle = (modplcphy_hd *) malloc(sizeof(modplcphy_hd)); if (!handle) return NULL; /* Inicializa el manejador de interfaz con la capa fsica del modem PLC. */ while(1) { /* Abre una conexin con la cola de mensajes del driver del modem PLC. */ sprintf(qname, "\\\\.\\pipe\\modemplc%i", sid); handle->hq = CreateFile(qname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (handle->hq == INVALID_HANDLE_VALUE) break; /* Inicializa el manejador de tramas capturadas de cada una de las interfaces fsicas. */ for(iface = 0; iface < 256; iface ++) { handle->iface[iface].recfun = NULL; handle->iface[iface].param = NULL; } /* Inicializa semforo de exclusin mtua. */ handle->hm = CreateSemaphore(NULL, 1, 1, NULL); if (handle->hm == INVALID_HANDLE_VALUE) break; /* Solicita acceder a la capa fsica del modem PLC. */ layer = 1; if (!__modplcphy_sendrecv__(handle, &result, sizeof(result), &layer, sizeof(layer))) break; if (!result) break; /* Devuelve el manejador creado. */ return handle; } /* No se pudo inicializar la interfaz con la capa fsica del modem PLC. */ CloseHandle(handle->hm); CloseHandle(handle->hq); free(handle); return NULL; } /* Funcin modplcphy_release: Libera los recursos utilizados por la capa fsica del modem PLC. */ int modplcphy_release(modplcphy_hd *hd) { /* Variables. */ int op; int result; short int iface;

/* Operacin. */ /* Resultado de la operacin. */ /* Identificadores de interfaces fsicas. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Libera el manejador de captura de tramas. */ for(iface = 0; iface < 256; iface ++) modplcphy_notify(hd, (unsigned char) (iface & 0x00ff), NULL, NULL);

FernandoArielBeunza79156

359

Tesis de Grado en Ingeniera Informtica


/* Solicita la finalizacin del acceso a la capa fsica del modem PLC. */ op = MODDRVPHY_RELEASE; if (!__modplcphy_sendrecv__(hd, &result, sizeof(result), &op, sizeof(op))) return 0; if (!result) return 0; /* Libera los recursos utilizados por la interfaz con la capa fsica del modem PLC. */ CloseHandle(hd->hm); CloseHandle(hd->hq); free(hd); /* xito. */ return 1; } /* Funcin modplcphy_sndframe: Enva una trama. */ size_t modplcphy_sndframe(modplcphy_hd *hd, unsigned char iface, const void *frame, size_t framesize) { /* Variables. */ int op; /* Identificador de operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Enva una trama. */ while(1) { /* Solicita el envo de una trama. */ op = MODDRVPHY_SNDFRAME; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ if (!__modplcphy_sendrecv__(hd, NULL, 0, &iface, sizeof(iface))) break; /* Enva el tamao de la trama. */ if (!__modplcphy_sendrecv__(hd, NULL, 0, &framesize, sizeof(framesize))) break; /* Enva la trama. */ if (!__modplcphy_sendrecv__(hd, &framesize, sizeof(framesize), frame, framesize)) break; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve la cantidad de bytes enviados. */ return framesize; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* No se pudo realizar el envo. */ return 0; } /*

360

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Funcin modplcphy_capframe: Captura una trama. */ int modplcphy_capframe(modplcphy_hd *hd, unsigned char iface, size_t framesize) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Solicita la captura una trama. */ result = 0; while(1) { /* Solicita la captura de una trama. */ op = MODDRVPHY_CAPFRAME; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ if (!__modplcphy_sendrecv__(hd, NULL, 0, &iface, sizeof(iface))) break; /* Enva el tamao de la trama. */ __modplcphy_sendrecv__(hd, &result, sizeof(result), &framesize, sizeof(framesize)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve el resultado de la solicitud. */ return result; } /* Funcin modplcphy_getframe: Obtiene una trama capturada previamente. */ size_t modplcphy_getframe(modplcphy_hd *hd, unsigned char iface, void *frame, size_t framesize) { /* Variables. */ int op; /* Identificador de operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Obtiene una trama capturada previamente. */ while(1) { /* Solicita la leer una trama. */ op = MODDRVPHY_GETFRAME; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ if (!__modplcphy_sendrecv__(hd, NULL, 0, &iface, sizeof(iface))) break; /* Enva el tamao de la trama y obtiene la trama. */ if (!__modplcphy_sendrecv__(hd, frame, framesize, &framesize,

FernandoArielBeunza79156

361

Tesis de Grado en Ingeniera Informtica


sizeof(framesize))) break; /* Obtiene el tamao de la trama leda. */ if (!__modplcphy_sendrecv__(hd, &framesize, sizeof(framesize), NULL, 0)) break; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve la cantidad de bytes ledos. */ return framesize; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* No se pudo obtener la trama capturada. */ return 0; } /* Funcin modplcphy_notify: Define una funcin manejadora de tramas capturadas. */ int modplcphy_notify(modplcphy_hd *hd, unsigned char iface, void (*func)(modplcphy_hd *, void *), void *param) { /* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Si la funcin manejadora es nula y no hay ninguna funcin manejadora definida previamente no se hace nada. */ if ((!func) && (!hd->iface[iface].recfun)) return 1; /* Si la funcin manejadora no es nula y hay una funcin manejadora previamente definida actualiza la funcin manejadora. */ if ((func) && (hd->iface[iface].recfun)) { WaitForSingleObject(hd->hm, INFINITE); hd->iface[iface].recfun = func; hd->iface[iface].param = param; ReleaseSemaphore(hd->hm, 1, NULL); return 1; } /* Si la funcin manejadora es nula y hay una funcin manejadora definida previamente se elimina esta ltima. */ if ((!func) && (hd->iface[iface].recfun)) { WaitForSingleObject(hd->hm, INFINITE); hd->iface[iface].recfun = NULL; hd->iface[iface].param = param; ReleaseSemaphore(hd->hm, 1, NULL); WaitForSingleObject(hd->iface[iface].detectthread, INFINITE); return 1; } /* Si la funcin manejadora no es nula y no hay una funcin manejadora previamente definida se define la nueva funcin manejadora. */ if ((func) && (!hd->iface[iface].recfun)) { WaitForSingleObject(hd->hm, INFINITE); hd->iface[iface].recfun = func; hd->iface[iface].param = param; hd->iface[iface].detectthread = CreateThread(NULL, 0, __modplcphy_detectproc__, hd, 0, &(hd->iface[iface].threadid));

362

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


if (hd->iface[iface].detectthread == INVALID_HANDLE_VALUE) { hd->iface[iface].recfun = NULL; hd->iface[iface].param = NULL; ReleaseSemaphore(hd->hm, 1, NULL); return 0; } ReleaseSemaphore(hd->hm, 1, NULL); return 1; } /* No se pudo definir la funcin manejadora de tramas capturadas. */ return 0; } /* Funcin modplcphy_poll: Verifica la captura de una trama. */ int modplcphy_poll(modplcphy_hd *hd, unsigned char iface) { /* Variables. */ int op; int result;

/* Identificador de operacin. */ /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Verifica la captura de una trama. */ result = 0; while(1) { /* Solicita verificar la captura de una trama. */ op = MODDRVPHY_POLL; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ __modplcphy_sendrecv__(hd, &result, sizeof(result), &iface, sizeof(iface)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve el resultado de la solicitud. */ return result; } /* Funcin modplcphy_rsdframe: Reenva una trama. */ int modplcphy_rsdframe(modplcphy_hd *hd, unsigned char iface) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE);

FernandoArielBeunza79156

363

Tesis de Grado en Ingeniera Informtica


/* Reenva una trama. */ result = 0; while(1) { /* Solicita reenviar una trama. */ op = MODDRVPHY_RSDFRAME; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ __modplcphy_sendrecv__(hd, &result, sizeof(result), &iface, sizeof(iface)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve el resultado del reenvo de la trama. */ return result; } /* Funcin modplcphy_clrbuffer: Limpia el buffer de captura de tramas. */ int modplcphy_clrbuffer(modplcphy_hd *hd, unsigned char iface) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Limpia el buffer de captura de tramas. */ result = 0; while(1) { /* Solicita limpiar el buffer de captura de tramas. */ op = MODDRVPHY_CLRBUFFER; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ __modplcphy_sendrecv__(hd, &result, sizeof(result), &iface, sizeof(iface)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve el resultado de la limpieza del buffer. */ return result; } /* Funcin modplcphy_sensechannel: Sensa el estado del canal de comunicacin. */ int modplcphy_sensechannel(modplcphy_hd *hd, unsigned char iface, unsigned char level, long int waittime) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

364

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Solicita el sensado del canal de comunicacin. */ result = 0; while(1) { /* Solicita el sensado del estado del canal de comunicacin. */ op = MODDRVPHY_SENSECHANNEL; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ if (!__modplcphy_sendrecv__(hd, NULL, 0, &iface, sizeof(iface))) break; /* Enva el nivel de seal. */ if (!__modplcphy_sendrecv__(hd, NULL, 0, &level, sizeof(level))) break; /* Enva el tiempo de espera. */ __modplcphy_sendrecv__(hd, &result, sizeof(result), &waittime, sizeof(waittime)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve el resultado del sensado del estado del canal de comunicacin. */ return result; } /* Funcin modplcphy_gensignal: Genera la seal especificada por medio de la capa fsica del modem PLC. */ int modplcphy_gensignal(modplcphy_hd *hd, unsigned char iface, int sig) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Solicita la generacin de la seal especificada. */ result = 0; while(1) { /* Solicita la generacin de una seal. */ op = MODDRVPHY_GENSIGNAL; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ if (!__modplcphy_sendrecv__(hd, NULL, 0, &iface, sizeof(iface))) break; /* Enva el tipo de seal. */ __modplcphy_sendrecv__(hd, &result, sizeof(result), &sig, sizeof(sig)); break; }

FernandoArielBeunza79156

365

Tesis de Grado en Ingeniera Informtica


/* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve el resultado de la solicitud. */ return result; } /* Funcin modplcphy_tstreceive: Realiza una prueba de recepcin. */ int modplcphy_tstreceive(modplcphy_hd *hd, unsigned char iface) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Realiza una prueba de recepcin. */ result = 0; while(1) { /* Solicita realizar una prueba de recepcin. */ op = MODDRVPHY_TSTRECEIVE; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ __modplcphy_sendrecv__(hd, &result, sizeof(result), &iface, sizeof(iface)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve el resultado de la prueba de recepcin. */ return result; } /* Funcin modplcphy_status: Devuelve el estado del modem PLC. */ int modplcphy_status(modplcphy_hd *hd) { /* Variables. */ int op; int result;

/* Identificador de operacin. */ /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Obtiene el estado del modem PLC. */ op = MODDRVPHY_STATUS; if (!__modplcphy_sendrecv__(hd, &result, sizeof(result), &op, sizeof(op))) result = 0; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL);

366

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Devuelve el estado del modem PLC. */ return result; } /* Funcin modplcphy_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener una trama de la capa fsica del modem PLC. */ size_t modplcphy_getpayloadsize(modplcphy_hd *hd, unsigned char iface) { /* Variables. */ int op; /* Operacin. */ size_t payloadsize; /* Cantidad de bytes que puede contener una trama. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); payloadsize = 0; while(1) { /* Obtiene la cantidad mxima de bytes que puede contener una trama. */ op = MODDRVPHY_GETPAYLOADSIZE; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ __modplcphy_sendrecv__(hd, &payloadsize, sizeof(payloadsize), &iface, sizeof(iface)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Devuelve la cantidad mxima de bytes que puede contener una trama. */ return payloadsize; }

/* Implementacin de funciones privadas. */ /* Funcin __modplcphy_detectproc__: Verifica la existencia de una trama capturada disponible para ser leda. */ static DWORD WINAPI __modplcphy_detectproc__(LPVOID param) { /* Variables. */ int op; /* Identificador de operacin. */ int captureflag; /* Indicador de captura de una trama. */ short int i; /* Contador. */ unsigned char iface; /* Identificadores de interfaces fsicas. */ modplcphy_hd *hd; /* Manejador de interfaz con la capa fsica del modem PLC. */ void (*func)(void *, void *); /* Manejador de captura de tramas. */

/* Carga el manejador de interfaz con la capa fsica del modem PLC. */ hd = (modplcphy_hd *) param; /* Obtiene el identificador de interface fsica asociado al hilo de

FernandoArielBeunza79156

367

Tesis de Grado en Ingeniera Informtica


deteccin de recepcin. */ iface = 0; WaitForSingleObject(hd->hm, INFINITE); for(i = 0; i < 256; i++) { if (hd->iface[i].threadid != GetCurrentThreadId()) continue; iface = (unsigned char) (i & 0x00ff); break; } ReleaseSemaphore(hd->hm, 1, NULL); if (i > 255) return 0; /* Verifica la existencia de una trama capturada. */ while(1) { /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ WaitForSingleObject(hd->hm, INFINITE); /* Verifica la captura de una trama. */ func = hd->iface[iface].recfun; if (!func) break; captureflag = 0; while(1) { /* Solicita verificar la captura de una trama. */ op = MODDRVPHY_POLL; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ __modplcphy_sendrecv__(hd, &captureflag, sizeof(captureflag), &iface, sizeof(iface)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ ReleaseSemaphore(hd->hm, 1, NULL); /* Verifica si se ha detectado la captura de una trama para invocar al manejador de trama capturadas. */ if (captureflag) func(hd, hd->iface[iface].param); } /* Fin de ejecucin del hilo de deteccin de recepcin. */ ReleaseSemaphore(hd->hm, 1, NULL); return 0; } /* Funcin __modplcphy_sendrecv__: Intercambia datos con el driver del modem PLC. */ static int __modplcphy_sendrecv__(modplcphy_hd *hd, void *outdata, size_t outsize, const void *indata, size_t insize) { /* Variables. */ size_t last; /* Cantidad de bytes enviados o recibidos. */ size_t sent; /* Cantidad de bytes enviados. */ size_t received; /* Cantidad de bytes recibidos. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Enva la operacin. */ sent = 0; while((indata) && (sent < insize))

368

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


{ if (!WriteFile(hd->hq, indata, insize, &last, NULL)) return 0; sent += last; } /* Recibe la respuesta. */ received = 0; while((outdata) && (received < outsize)) { if (!ReadFile(hd->hq, outdata, outsize, &last, NULL)) return 0; received += last; } /* xito. */ return 1; }

C.3.4. Driver del Modem PLC modem_driver.exe


En esta seccin se detalla el cdigo fuente del driver del modem PLC, que se compone de los siguientes archivos:

Archivo config.h: en este archivo se definen parmetros de configuracin del driver del del modem PLC que no pueden ser modificados en tiempo de ejecucin. Archivo serial.h: en este archivo se declaran primitivas con funcionalidades referentes a la comunicacin por puerto serie. Archivo serial.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo serial.h. Archivo modplc.h: en este archivo se declaran las primitivas correspondientes al interfaz con la capa fsica, de enlace y de sesin. Dichas primitivas brindan un conjunto de funcionalidades que permiten la comunicacin con las capas mencionadas implementadas en el modem PLC. Archivo modplc.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo modplc.h. Archivo modsp.h: en este archivo se declaran las primitivas correspondientes al interfaz con la capa de sesin. Dichas primitivas brindan un conjunto de funcionalidades que permiten la comunicacin con las capa de sesin implementada en el modem PLC. Archivo modsp.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo modsp.h. Archivo moddl.h: en este archivo se declaran las primitivas correspondientes al interfaz con la capa de enlace. Dichas primitivas brindan un conjunto de funcionalidades que permiten la comunicacin con las capa de enlace implementada en el modem PLC. Archivo moddl.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo moddl.h.

FernandoArielBeunza79156

369

Tesis de Grado en Ingeniera Informtica

Archivo modphy.h: en este archivo se declaran las primitivas correspondientes al interfaz con la capa fsica. Dichas primitivas brindan un conjunto de funcionalidades que permiten la comunicacin con las capa fsica implementada en el modem PLC. Archivo modphy.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo modphy.h. Archivo moddrv.h: en este archivo se declaran las primitivas correspondientes al driver del modem PLC. Dichas primitivas brindan un conjunto de funcionalidades que permite a las interfaces mencionadas anteriormente comunicarse con el modem PLC. Archivo moddrv.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo moddrv.h. Archivo modem_driver.c: en este archivo se encuentra implementada la inicializacin de la ejecucin del driver del modem PLC.

C.3.4.1. Archivo config.h


/* config.h Definicin de parmetros de configuracin. */

#if !defined(__CONFIG_H__) #define __CONFIG_H__

/* Interfaz del modem PLC. */ /* Tipos de prompt utilizados. */ #define MODPLC_INITPROMPT #define MODPLC_LAYPROMPT #define MODPLC_NORMPROMPT #define MODPLC_PARAMPROMPT /* Tipos de reset. */ #define MODPLC_NORMRESET #define MODPLC_PARAMRESET /* Cdigo de operaciones de la capa fsica. */ #define MODPLCPHY_RESET #define MODPLCPHY_SNDFRAME #define MODPLCPHY_CAPFRAME #define MODPLCPHY_GETFRAME #define MODPLCPHY_POLL #define MODPLCPHY_RSDFRAME #define MODPLCPHY_CLRBUFFER #define MODPLCPHY_SENSECHANNEL #define MODPLCPHY_GENSIGNAL #define MODPLCPHY_TSTRECEIVE #define MODPLCPHY_GETPAYLOADSIZE /* Tipos de seal. */ #define MODPLCPHY_NOISESIGNAL #define MODPLCPHY_TESTSIGNAL1 #define MODPLCPHY_TESTSIGNAL2 /* Cdigo de operaciones de la capa de enlace. */ #define MODPLCDL_RESET

'#' '?' '$' '>'

'0' '$'

MODPLC_NORMRESET '1' '2' '3' '4' '5' '6' '7' '8' '9' 'a'

0x01 0x02 0x03

MODPLC_NORMRESET

370

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


#define #define #define #define #define #define #define #define #define #define MODPLCDL_OPEN MODPLCDL_CLOSE MODPLCDL_SEND MODPLCDL_RECEIVE MODPLCDL_POLL MODPLCDL_GETADDRESS MODPLCDL_ADDLOGADDRESS MODPLCDL_DELLOGADDRESS MODPLCDL_GETPHYADDRESS MODPLCDL_GETPAYLOADSIZE '1' '2' '3' '4' '5' '6' '7' '8' '9' 'a'

/* Cdigo de operaciones de la capa de sesin. */ #define MODPLCSP_RESET #define MODPLCSP_PUBLISH #define MODPLCSP_SUBSCRIBE #define MODPLCSP_LEAVE #define MODPLCSP_SEND #define MODPLCSP_RECEIVE #define MODPLCSP_POLL #define MODPLCSP_GETPAYLOADSIZE

MODPLC_NORMRESET '1' '2' '3' '4' '5' '6' '7'

/* Driver del modem PLC. */ /* Cdigos de operaciones de la interfaz de la capa fsica. */ #define MODDRVPHY_RELEASE 0x00 #define MODDRVPHY_SNDFRAME 0x01 #define MODDRVPHY_CAPFRAME 0x02 #define MODDRVPHY_GETFRAME 0x03 #define MODDRVPHY_POLL 0x04 #define MODDRVPHY_RSDFRAME 0x05 #define MODDRVPHY_CLRBUFFER 0x06 #define MODDRVPHY_SENSECHANNEL 0x07 #define MODDRVPHY_GENSIGNAL 0x08 #define MODDRVPHY_TSTRECEIVE 0x09 #define MODDRVPHY_STATUS 0x0a #define MODDRVPHY_GETPAYLOADSIZE 0x0b /* Cdigos de operaciones de la interfaz de la capa de enlace. */ #define MODDRVDL_CLOSE 0x00 #define MODDRVDL_OPEN 0x01 #define MODDRVDL_SEND 0x02 #define MODDRVDL_RECEIVE 0x03 #define MODDRVDL_POLL 0x04 #define MODDRVDL_GETADDRESS 0x05 #define MODDRVDL_ADDLOGADDRESS 0x06 #define MODDRVDL_DELLOGADDRESS 0x07 #define MODDRVDL_GETPHYADDRESS 0x08 #define MODDRVDL_STATUS 0x09 #define MODDRVDL_GETPAYLOADSIZE 0x0a /* Cdigos de operaciones de la interfaz de la capa de sesin. */ #define MODDRVSP_RELEASE 0x00 #define MODDRVSP_PUBLISH 0x01 #define MODDRVSP_SUBSCRIBE 0x02 #define MODDRVSP_LEAVE 0x03 #define MODDRVSP_SEND 0x04 #define MODDRVSP_RECEIVE 0x05 #define MODDRVSP_POLL 0x06 #define MODDRVSP_STATUS 0x07 #define MODDRVSP_GETPAYLOADSIZE 0x08

/* Interfaz con el modem PLC. */ /* Tamao del buffer. */ #define MODPLC_BUFFERSIZE /* Cantidad de bytes de una lnea por envo. */ #define MODPLC_FRAGMENTLINESIZE

4096

FernandoArielBeunza79156

371

Tesis de Grado en Ingeniera Informtica


#endif

C.3.4.2. Archivo serial.h


/* serial.h: Declaracin de funciones referentes a la interfaz de comunicacin por puerto serie. */

#if !defined(__SERIAL_H__) #define __SERIAL_H__

/* Archivos includos necesarios. */ #include "config.h" #include <windows.h>

/* Definicin de tipos. */ /* Manejador de interfaz de comunicacin por puerto serie. */ typedef struct { HANDLE serialhd; /* Manejador de interfaz de puerto serie. */ HANDLE stopsem; /* Semforo de finalizacin de recepcin. */ HANDLE readersem; /* Semforo lector del buffer de recepcin. */ HANDLE writersem; /* Semforo escritor del buffer de recepcin. */ HANDLE recvthread; /* Manejador de hilo receptor. */ int stopflag; /* Indicador de fin de recepcin. */ size_t size; /* Tanao del buffer de recepcin. */ size_t received; /* Cantidad de bytes recibidos sin leer. */ char *buffer; /* Puntero al buffer de recepcin. */ } serial_hd;

/* Declaracin de funciones pblicas. */ /* Funcin serial_init: Inicializa la interfaz de comunicacin por puerto serie. */ serial_hd *serial_init(int, size_t); /* Funcin serial_release: Libera los recursos utilizdos por la interfaz de comunicacin por puerto serie. */ int serial_release(serial_hd *); /* Funcin serial_send: Enva un mensaje a travs de la interfaz de comunicacin por puerto serie. */ size_t serial_send(serial_hd *, const void *, size_t); /*

372

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Funcin serial_receive: Recibe un mensaje a por medio de la interfaz de comunicacin por puerto serie. */ size_t serial_receive(serial_hd *, void *, size_t); /* Funcin serial_poll: Devuelve si hay un mensaje a la espera de ser recibido. */ int serial_poll(serial_hd *);

#endif

C.3.4.3. Archivo serial.c


/* serial.c: Implementacin de funciones referentes a la interfaz de comunicacin por puerto serie. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdio.h> #include <windows.h> #include <process.h> #include "serial.h"

/* Declaracin de funciones privadas. */ static DWORD WINAPI __serial_recvproc__(LPVOID);

/* Implementacin de funciones pblicas. */ /* Funcin serial_init: Inicializa la interfaz de comunicacin por puerto serie. */ serial_hd *serial_init(int id, size_t buffsize) { /* Variables. */ DWORD tid; DCB icfg;

COMMTIMEOUTS cto; serial_hd *handle; char iname[256];

/* Identificador de hilo. */ /* Configuracin de la interfaz de comunicacin por puerto serie. */ /* Configuracin de los tiempos de espera. */ /* Manejador de la interfaz. */ /* Nombre de la interfaz. */

/* Verifica la validez del identificador de la interfaz de comunicacin por puerto serie. */ if (id < 1) return 0; /* Crea un nuevo manejador de interfaz de comunicacin por puerto serie. */ handle = (serial_hd *) malloc(sizeof(serial_hd)); if (!handle) return NULL; /* Inicializa el buffer de recepcin. */ handle->buffer = (char *) malloc(buffsize); if (!handle->buffer) { free(handle);

FernandoArielBeunza79156

373

Tesis de Grado en Ingeniera Informtica


return NULL; } handle->received = 0; handle->size = buffsize; /* Inicializa la interfaz de comunicacin por puerto serie. */ while(1) { /* Abre la interfaz de comunicacin por puerto serie. */ if (id < 9) sprintf(iname, "COM%i", id); else sprintf(iname, "\\\\.\\COM%i", id); handle->serialhd = CreateFile(iname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (handle->serialhd == INVALID_HANDLE_VALUE) break; /* Configura la interfaz de comunicacin por puerto serie. */ icfg.DCBlength = sizeof(DCB); if (!GetCommState(handle->serialhd, &icfg)) break; icfg.BaudRate = CBR_57600; icfg.ByteSize = 8; icfg.Parity = NOPARITY; icfg.fParity = FALSE; icfg.StopBits = ONESTOPBIT; if (!SetCommState(handle->serialhd, &icfg)) break; /* Configura los tiempos de espera de la interfaz de comunicacin por puerto serie. */ if (!GetCommTimeouts(handle->serialhd, &cto)) break; cto.ReadIntervalTimeout = 5; cto.WriteTotalTimeoutConstant = 5000; if (!SetCommTimeouts(handle->serialhd, &cto)) break; /* Limpia los buffers de la interfaz de comunicacin por puerto serie. */ if (!PurgeComm(handle->serialhd, PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR)) break; /* Inicializa semforos. */ handle->stopflag = 0; handle->stopsem = CreateSemaphore(NULL, 0, 1, NULL); if (handle->stopsem == INVALID_HANDLE_VALUE) break; handle->readersem = CreateSemaphore(NULL, 0, 1, NULL); if (handle->readersem == INVALID_HANDLE_VALUE) break; handle->writersem = CreateSemaphore(NULL, 1, 1, NULL); if (handle->writersem == INVALID_HANDLE_VALUE) break; /* Inicializa el hilo de recepcin. */ handle->recvthread = CreateThread(NULL, 0, __serial_recvproc__, handle, 0, &tid); if (handle->recvthread == INVALID_HANDLE_VALUE) break; /* Devuelve el manejador de la interfaz de comunicacin por puerto serie. */ return handle; } /* No se pudo inicializar la interfaz de comunicacin por puerto serie. */ CloseHandle(handle->writersem); CloseHandle(handle->readersem); CloseHandle(handle->stopsem); CloseHandle(handle->serialhd); free(handle->buffer); free(handle); return NULL; }

374

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin serial_release: Libera los recursos utilizdos por la interfaz de comunicacin por puerto serie. */ int serial_release(serial_hd *hd) { /* Verifica la validez del manejador de la interfaz de comunicacin por puerto serie. */ if (!hd) return 0; /* Detiene la ejecucin del hilo de recepcin. */ ReleaseSemaphore(hd->writersem, 1, NULL); ReleaseSemaphore(hd->stopsem, 1, NULL); WaitForSingleObject(hd->recvthread, INFINITE); /* Libera los recursos utilizados por la interfaz de comunicacin por puerto serie. */ CloseHandle(hd->writersem); CloseHandle(hd->readersem); CloseHandle(hd->stopsem); CloseHandle(hd->serialhd); free(hd->buffer); free(hd); /* xito. */ return 1; } /* Funcin serial_send: Enva un mensaje a travs de la interfaz de comunicacin por puerto serie. */ size_t serial_send(serial_hd *hd, const void *msg, size_t msgsize) { /* Variables. */ int result; /* Resultado de la espera. */ size_t sent; /* Cantidad de bytes enviados. */ size_t lastsend; /* Cantidad de bytes envados en el ltimo envo. */ OVERLAPPED ovl; /* Manejador de comunicacin asincrnica. */ unsigned char *ptr; /* Puntero al mensaje. */

/* Verifica la validez del manejador de la interfaz de comunicacin por puerto serie. */ if (!hd) return 0; /* Enva los bytes especificados por medio de la interfaz de comunicacin por puerto serie. */ sent = 0; ptr = (unsigned char *) msg; memset(&ovl, 0, sizeof(ovl)); while(msgsize && (!hd->stopflag)) { /* Enva los bytes especificados. */ do { lastsend = 0; ovl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (!ovl.hEvent) break; if (!WriteFile(hd->serialhd, ptr, msgsize, &lastsend, &ovl)) { if (GetLastError() != ERROR_IO_PENDING) break; else { result = WaitForSingleObject(ovl.hEvent, INFINITE); if (result == WAIT_OBJECT_0)

FernandoArielBeunza79156

375

Tesis de Grado en Ingeniera Informtica


{ if (!GetOverlappedResult(hd->serialhd, &ovl, &lastsend, FALSE)) break; } else break; } } CloseHandle(ovl.hEvent); } while(!lastsend); /* Actualiza contadores y puntero a los bytes a bytes a enviar en base a la cantidad de bytes enviados anteriormente. */ msgsize -= lastsend; sent += lastsend; ptr += lastsend; } /* Devuelve la cantidad de bytes enviados. */ return sent; } /* Funcin serial_receive: Recibe un mensaje por medio de la interfaz de comunicacin por puerto serie. */ size_t serial_receive(serial_hd *hd, void *msg, size_t msgsize) { /* Variables. */ size_t received; /* Cantidad de bytes recibidos. */

/* Verifica la validez del manejador de la interfaz de comunicacin por puerto serie. */ if (!hd) return 0; /* Espera a que el buffer de recepcin tenga algn contenido. */ if (WaitForSingleObject(hd->readersem, INFINITE) != WAIT_OBJECT_0) return 0; /* Lee la cantidad especificada de bytes del buffer de recepcin. */ received = msgsize; if (received > hd->received) received = hd->received; memcpy(msg, hd->buffer, received); /* Actualiza el buffer de recepcin. */ if (hd->received - received) memcpy(hd->buffer, hd->buffer + received, hd->received - received); hd->received -= received; /* Si el buffer no se encuentra lleno habilita al hilo receptor. */ if (hd->received < hd->size) ReleaseSemaphore(hd->writersem, 1, NULL); /* Devuelve la cantidad de bytes recibidos. */ return received; } /* Funcin serial_poll: Verifica la llegada de un nuevo mensaje. */ int serial_poll(serial_hd *hd) { /* Verifica la validez del manejador de la interfaz de comunicacin por puerto serie. */ if (!hd) return 0; /* Verifica si el buffer no se encuentra vaco. */ return (hd->received != 0);

376

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


}

/* Implementacin de funciones privadas. */ /* Funcin __serial_recvproc__: Recibe datos por la interfaz de comunicacin por puerto serie y lo almacena en el buffer de recepcin. */ static DWORD WINAPI __serial_recvproc__(LPVOID param) { /* Variables. */ int result; size_t received; OVERLAPPED ovl; HANDLE waiters[2]; serial_hd *hd;

/* Resultado de la espera. */ /* Cantidad de bytes recibidos. */ /* Manejador de comunicacin asincrnica. */ /* Manejadores en espera. */ /* Manejador de la interfaz por puerto serie. */

/* Carga el manejador de comunicacin por puerto serie. */ hd = (serial_hd *) param; /* Inicializa la comunicacin asincrnica. */ memset(&ovl, 0, sizeof(ovl)); ovl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (ovl.hEvent == INVALID_HANDLE_VALUE) { hd->stopflag = 1; ExitThread(0); return 0; } waiters[0] = hd->stopsem; waiters[1] = ovl.hEvent; /* Lee la interfaz de comunicacin por puerto serie. */ while(1) { /* Verifica si hay una peticin de finalizacin de ejecucin del hilo receptor. */ if (WaitForSingleObject(hd->stopsem, 0) == WAIT_OBJECT_0) break; /* Espera a que el buffer de recepcin deje de ser ledo. */ if (WaitForSingleObject(hd->writersem, INFINITE) != WAIT_OBJECT_0) break; /* Carga en el buffer los bytes recibidos. */ if (!ReadFile(hd->serialhd, hd->buffer + hd->received, hd->size - hd->received, &received, &ovl)) { if (GetLastError() != ERROR_IO_PENDING) break; else { result = WaitForMultipleObjects(2, waiters, FALSE, INFINITE); if (result == WAIT_OBJECT_0) { CancelIo(hd->serialhd); break; } else if (result == WAIT_OBJECT_0 + 1) { if (!GetOverlappedResult(hd->serialhd, &ovl, &hd->received, FALSE)) break; } else break; }

FernandoArielBeunza79156

377

Tesis de Grado en Ingeniera Informtica


} hd->received += received; /* Habilita la lectura del buffer de recepcin. */ ReleaseSemaphore(hd->readersem, 1, NULL); } CloseHandle(ovl.hEvent); /* Termina la ejecucin del hilo de recepcin. */ hd->stopflag = 1; ExitThread(0); return 0; }

C.3.4.4. Archivo modplc.h


/* modplc.h: Declaracin de funciones referentes a la interfaz con el modem PLC. */

#if !defined(__MODPLC_H__) #define __MODPLC_H__

/* Archivos includos necesarios. */ #include "config.h" #include "serial.h"

/* Definicin de tipos. */ /* Direccin fsica del modem PLC. */ typedef unsigned char modplc_dlphyaddr[8]; /* Direccin lgica del modem PLC. */ typedef unsigned long int modplc_dllogaddr; /* Identificador de grupo. */ typedef unsigned char modplc_spgrpid; /* Manejador de interfaz con el modem PLC. */ typedef struct { serial_hd *serialhd;

int layer; int status; int debugmode; } modplc_hd;

/* Manejador de interfaz de comunicacin por puerto serie. */ /* Capa del modem PLC utilizada. */ /* Estado del modem PLC. */ /* Indicador de modo depuracin. */

/* Definicin de constantes. */ /* Capas de acceso. */ #define MODPLC_PHYSICALLAYER #define MODPLC_DATALINKLAYER #define MODPLC_SESSIONLAYER /* Tipos de seales. */ #define MODPLC_PHYNOISESIGNAL #define MODPLC_PHYTESTSIGNAL1 #define MODPLC_PHYTESTSIGNAL2

0x01 0x02 0x03

0x01 0x02 0x03

/* Declaracin de funciones pblicas. */

378

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin modplc_init: Inicializa los recursos utilizados por la interfaz con el modem PLC. */ modplc_hd *modplc_init(int, int, int); /* Funcin modplc_release: Libera los recursos utilizados por la interfaz con el modem PLC. */ int modplc_release(modplc_hd *); /* Funcin modplc_status: Devuelve el estado del modem PLC. */ int modplc_status(modplc_hd *); /* Funcin modplc_physndframe: Enva una trama por medio de la capa fsica del modem PLC. */ size_t modplc_physndframe(modplc_hd *, unsigned char, const void *, size_t); /* Funcin modplc_phycapframe: Captura una trama por medio de la capa fsica del modem PLC. */ int modplc_phycapframe(modplc_hd *, unsigned char, size_t); /* Funcin modplc_phygetframe: Obtiene una trama capturada previamente por medio de la capa fsica del modem PLC. */ size_t modplc_phygetframe(modplc_hd *, unsigned char, void *, size_t); /* Funcin phy_poll: Verifica la captura de una trama por medio de la capa fsica del modem PLC. */ int modplc_phypoll(modplc_hd *, unsigned char); /* Funcin modplc_phyrsdframe: Reenva una trama por medio de la capa fsica del modem PLC. */ int modplc_phyrsdframe(modplc_hd *, unsigned char); /* Funcin modplc_phyclrbuffer: Limpia el buffer de captura de tramas de la capa fsica del modem PLC. */ int modplc_phyclrbuffer(modplc_hd *, unsigned char); /* Funcin modplc_physensechannel: Sensa el estado del canal de comunicacin por medio de la capa fsica del modem PLC. */ int modplc_physensechannel(modplc_hd *, unsigned char, unsigned char, long int); /* Funcin modplc_phygensignal: Genera la seal especificada por medio de la capa fsica del modem PLC. */ int modplc_phygensignal(modplc_hd *, unsigned char, int); /*

FernandoArielBeunza79156

379

Tesis de Grado en Ingeniera Informtica


Funcin modplc_phytstreceive: Realiza una prueba de recepcin de la capa fsica del modem PLC. */ int modplc_phytstreceive(modplc_hd *, unsigned char); /* Funcin modplc_phygetpayloadsize: Devuelve la cantidad mxima de bytes que puede contener una trama de la capa fsica del modem PLC. */ size_t modplc_phygetpayloadsize(modplc_hd *, unsigned char); /* Funcin modplc_dlopen: Abre una conexin por medio de la capa de enlace del modem PLC. */ int modplc_dlopen(modplc_hd *, unsigned char, unsigned char); /* Funcin modplc_dlclose: Cierra una conexin por medio de la capa de enlace del modem PLC. */ int modplc_dlclose(modplc_hd *, int); /* Funcin modplc_dlsend: Enva un mensaje por medio de la capa de enlace del modem PLC. */ size_t modplc_dlsend(modplc_hd *, int, modplc_dlphyaddr, unsigned char, const void *, size_t); /* Funcin modplc_dlreceive: Recibe un mensaje por medio de la capa de enlace del modem PLC. */ size_t modplc_dlreceive(modplc_hd *, int, modplc_dlphyaddr, void *, size_t); /* Funcin modplc_dlpoll: Verifica la llegada de un nuevo mensaje por medio de la capa de enlace del modem PLC. */ int modplc_dlpoll(modplc_hd *, int); /* Funcin modplc_dlgetaddress: Devuelve la direccin fsica de la capa de enlace del modem PLC. */ int modplc_dlgetaddress(modplc_hd *, unsigned char, modplc_dlphyaddr); /* Funcin modplc_dladdlogaddress: Agrega una nueva direccin lgica a la capa de enlace del modem PLC. */ int modplc_dladdlogaddress(modplc_hd *, unsigned char, unsigned char, modplc_dllogaddr); /* Funcin modplc_dldellogaddress: Elimina una direccin lgica a la capa de enlace del modem PLC. */ int modplc_dldellogaddress(modplc_hd *, unsigned char, unsigned char, modplc_dllogaddr); /* Funcin modplc_dlgetphyaddress: Devuelve la direccin fsica asociada a la direccin lgica de la capa de enlace del modem PLC. */ int modplc_dlgetphyaddress(modplc_hd *, unsigned char, unsigned char, modplc_dllogaddr, modplc_dlphyaddr);

380

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin modplc_dlgetpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de enlace del modem PLC. */ size_t modplc_dlgetpayloadsize(modplc_hd *, unsigned char); /* Funcin modplc_sppublish: Registra el dispositivo como publicador del grupo de difusin especificado de la capa de sesin del modem PLC. */ int modplc_sppublish(modplc_hd *, modplc_spgrpid); /* Funcin modplc_spsubscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado de la capa de sesin del modem PLC. */ int modplc_spsubscribe(modplc_hd *, modplc_spgrpid); /* Funcin modplc_spleave: Desvincula el dispositivo del grupo de difusin especificado de la capa de sesin del modem PLC. */ int modplc_spleave(modplc_hd *, modplc_spgrpid); /* Funcin modplc_spsend: Enva un mensaje por medio de la capa de sesin del modem PLC. */ size_t modplc_spsend(modplc_hd *, modplc_spgrpid, int, const void *, size_t); /* Funcin modplc_spreceive: Recibe un mensaje por medio de la capa de sesin del modem PLC. */ size_t modplc_spreceive(modplc_hd *, modplc_spgrpid *, void *, size_t); /* Funcin modplc_sppoll: Verifica la llegada de un nuevo mensaje por medio de la capa de sesin del modem PLC. */ int modplc_sppoll(modplc_hd *); /* Funcin modplc_spgetpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de sesin del modem PLC. */ size_t modplc_spgetpayloadsize(modplc_hd *);

#endif

C.3.4.5. Archivo modplc.c


/* modplc.c: Implementacin de funciones referentes a la interfaz con el modem PLC. */

/* Archivos includos necesarios. */ #include "config.h"

FernandoArielBeunza79156

381

Tesis de Grado en Ingeniera Informtica


#include <stdio.h> #include "serial.h" #include "modplc.h"

/* Declaracin de funciones privadas. */ static char __modplc_sendcmdline__(modplc_hd *, const char *, char *, size_t); static int __modplc_sendcmd__(modplc_hd *, char, const char *, void **, const void *, const char *, void **, void *);

/* Implementacin de funciones pblicas. */ /* Funcin modplc_init: Inicializa los recursos utilizados por la interfaz con el modem PLC. */ modplc_hd *modplc_init(int sid, int layer, int debugmode) { /* Variables. */ char prompt; modplc_hd *handle; char cmdline[MODPLC_BUFFERSIZE]; char respline[MODPLC_BUFFERSIZE];

/* Smbolo de la lnea de comando. */ /* Manejador de interfaz con el modem PLC. */ /* Lnea de comando. */ /* Lnea de respuesta de comando. */

/* Crea un nuevo manejador de interfaz con el modem PLC. */ handle = (modplc_hd *) malloc(sizeof(modplc_hd)); if (!handle) return NULL; /* Inicializa la interfaz de comunicacin por puerto serie. */ handle->serialhd = serial_init(sid, MODPLC_BUFFERSIZE); if (!handle->serialhd) { free(handle); return NULL; } /* Si es requerido establece el modo depuracin. */ handle->debugmode = 0; if (debugmode) handle->debugmode = 1; /* Inicializa la interfaz con el modem PLC. */ while(1) { /* Inicializa el modem PLC. */ *(cmdline + 0) = '\n'; *(cmdline + 1) = 0; prompt = __modplc_sendcmdline__(handle, cmdline, respline, MODPLC_BUFFERSIZE); if (prompt == MODPLC_INITPROMPT) sprintf(cmdline, "reset"); else if (prompt == MODPLC_LAYPROMPT) { *(cmdline + 0) = MODPLC_NORMRESET; *(cmdline + 1) = 0; } else if (prompt == MODPLC_NORMPROMPT) { *(cmdline + 0) = MODPLC_NORMRESET; *(cmdline + 1) = 0; } else if (prompt == MODPLC_PARAMPROMPT) { *(cmdline + 0) = MODPLC_PARAMRESET; *(cmdline + 1) = 0; } else

382

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


break; strcat(cmdline, "\n"); if (__modplc_sendcmdline__(handle, cmdline, respline, MODPLC_BUFFERSIZE) != MODPLC_INITPROMPT) break; sprintf(cmdline, "init\n"); if (__modplc_sendcmdline__(handle, cmdline, respline, MODPLC_BUFFERSIZE) != MODPLC_LAYPROMPT) break; /* Establece la capa a la cual se quiere acceder. */ handle->layer = layer; if (handle->layer == MODPLC_PHYSICALLAYER) *(cmdline + 0) = MODPLC_PHYSICALLAYER + '0'; else if (handle->layer == MODPLC_DATALINKLAYER) *(cmdline + 0) = MODPLC_DATALINKLAYER + '0'; else if (handle->layer == MODPLC_SESSIONLAYER) *(cmdline + 0) = MODPLC_SESSIONLAYER + '0'; else break; *(cmdline + 1) = '\n'; *(cmdline + 2) = 0; if (__modplc_sendcmdline__(handle, cmdline, respline, MODPLC_BUFFERSIZE) != MODPLC_NORMPROMPT) break; /* Modem PLC en estado activo. */ handle->status = 1; /* Devuelve el manejador creado. */ return handle; } /* No se pudo inicializar la interfaz con el modem PLC. */ modplc_release(handle); return NULL; } /* Funcin modplc_release: Libera los recursos utilizados por la interfaz con el modem PLC. */ int modplc_release(modplc_hd *hd) { /* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Libera la interfaz de comunicacin por puerto serie. */ serial_release(hd->serialhd); /* Libera los recursos utilizados por la interfaz con el modem PLC. */ free(hd); /* xito. */ return 1; } /* Funcin modplc_status: Devuelve el estado del modem PLC. */ int modplc_status(modplc_hd *hd) { /* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que el modem PLC se encuentre activo. */ if (!hd->status) return 0; if (__modplc_sendcmdline__(hd, "\n", NULL, MODPLC_BUFFERSIZE) == MODPLC_NORMPROMPT)

FernandoArielBeunza79156

383

Tesis de Grado en Ingeniera Informtica


return 1; hd->status = 0; return 0; } /* Funcin modplc_physndframe: Enva una trama por medio de la capa fsica del modem PLC. */ size_t modplc_physndframe(modplc_hd *hd, unsigned char iface, const void *frame, size_t framesize) { /* Variables. */ void *inparam[2]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Enva una trama. */ inparam[0] = &iface; inparam[1] = &framesize; outparam[0] = &framesize; if (__modplc_sendcmd__(hd, MODPLCPHY_SNDFRAME, "bs", inparam, frame, outparam, NULL)) return framesize; return 0; } /* Funcin modplc_phycapframe: Captura una trama por medio de la capa fsica del modem PLC. */ int modplc_phycapframe(modplc_hd *hd, unsigned char iface, size_t framesize) { /* Variables. */ unsigned char result; /* Resultado del comando. */ void *inparam[2]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

"s",

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Captura una trama. */ inparam[0] = &iface; inparam[1] = &framesize; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCPHY_CAPFRAME, "bs", inparam, NULL, outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_phygetframe: Obtiene una trama capturada previamente por medio de la capa fsica del modem PLC. */ size_t modplc_phygetframe(modplc_hd *hd, unsigned char iface, void *frame,

"b",

384

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


size_t framesize) { /* Variables. */ void *inparam[2]; void *outparam[1]; /* Parmetros de entrada del comando. */ /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Obtiene una trama capturada. */ inparam[0] = &iface; inparam[1] = &framesize; outparam[0] = &framesize; if (__modplc_sendcmd__(hd, MODPLCPHY_GETFRAME, "bs", inparam, NULL, outparam, frame)) return framesize; return 0; } /* Funcin modplc_phypoll: Verifica la captura de una trama por medio de la capa fsica del modem PLC. */ int modplc_phypoll(modplc_hd *hd, unsigned char iface) { /* Variables. */ unsigned char result; void *inparam[1]; void *outparam[1];

"s",

/* Resultado del comando. */ /* Parmetros de entrada del comando. */ /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Verifica la captura de una trama. */ inparam[0] = &iface; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCPHY_POLL, "b", inparam, NULL, outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_phyrsdframe: Reenva una trama por medio de la capa fsica del modem PLC. */ int modplc_phyrsdframe(modplc_hd *hd, unsigned char iface) { /* Variables. */ unsigned char result; /* Resultado del comando. */ void *inparam[1]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

"b",

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0;

FernandoArielBeunza79156

385

Tesis de Grado en Ingeniera Informtica


/* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Reenva una trama. */ inparam[0] = &iface; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCPHY_RSDFRAME, "b", inparam, NULL, outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_phyclrbuffer: Limpia el buffer de captura de tramas de la capa fsica del modem PLC. */ int modplc_phyclrbuffer(modplc_hd *hd, unsigned char iface) { /* Variables. */ unsigned char result; /* Resultado del comando. */ void *inparam[1]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

"b",

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Limpia el buffer de captura de tramas. */ inparam[0] = &iface; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCPHY_CLRBUFFER, "b", inparam, NULL, outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_physensechannel: Sensa el estado del canal de comunicacin por medio de la capa fsica del modem PLC. */ int modplc_physensechannel(modplc_hd *hd, unsigned char iface, unsigned char level, long int waittime) { /* Variables. */ unsigned char result; /* Resultado del comando. */ void *inparam[3]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

"b",

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Sensa el estado del canal de comunicacin. */ inparam[0] = &iface; inparam[1] = &level; inparam[2] = &waittime; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCPHY_SENSECHANNEL, "bbl", inparam, NULL, "b", outparam, NULL)) return (result == 1);

386

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


return 0; } /* Funcin modplc_phygensignal: Genera la seal especificada por medio de la capa fsica del modem PLC. */ int modplc_phygensignal(modplc_hd *hd, unsigned char iface, int sig) { /* Variables. */ unsigned char result; /* Resultado del comando. */ void *inparam[2]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Genera la seal especificada. */ inparam[0] = &iface; inparam[1] = &sig; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCPHY_GENSIGNAL, "bb", inparam, NULL, outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_phytstreceive: Realiza una prueba de recepcin de la capa fsica del modem PLC. */ int modplc_phytstreceive(modplc_hd *hd, unsigned char iface) { /* Variables. */ unsigned char result; /* Resultado del comando. */ void *inparam[1]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

"b",

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Realiza una prueba de recepcin. */ inparam[0] = &iface; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCPHY_TSTRECEIVE, "b", inparam, NULL, outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_phygetpayloadsize: Devuelve la cantidad mxima de bytes que puede contener una trama de la capa fsica del modem PLC. */ size_t modplc_phygetpayloadsize(modplc_hd *hd, unsigned char iface) { /* Variables. */ unsigned short int payloadsize; /* Cantidad mxima de bytes que

"b",

FernandoArielBeunza79156

387

Tesis de Grado en Ingeniera Informtica


void *inparam[1]; void *outparam[1]; puede contener una trama. */ /* Parmetros de entrada del comando. */ /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Devuelve la cantidad mxima de byes que puede contener una trama. */ inparam[0] = &iface; outparam[0] = &payloadsize; if (__modplc_sendcmd__(hd, MODPLCPHY_GETPAYLOADSIZE, "b", inparam, NULL, "s", outparam, NULL)) return (size_t) payloadsize; return 0; } /* Funcin modplc_dlopen: Abre una conexin por medio de la capa de enlace del modem PLC. */ int modplc_dlopen(modplc_hd *hd, unsigned char iface, unsigned char prot) { /* Variables. */ unsigned short int handle; /* Manejador de conexin. */ void *inparam[2]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0; /* Abre una conexin. */ inparam[0] = &iface; inparam[1] = &prot; outparam[0] = &handle; if (__modplc_sendcmd__(hd, MODPLCDL_OPEN, "bb", inparam, NULL, outparam, NULL)) return (int) handle; return 0; } /* Funcin modplc_dlclose: Cierra una conexin por medio de la capa de enlace del modem PLC. */ int modplc_dlclose(modplc_hd *hd, int handle) { /* Variables. */ unsigned char result; void *inparam[2]; void *outparam[1];

"s",

/* Resultado del comando. */ /* Parmetros de entrada del comando. */ /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0;

388

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Cierra una conexin. */ inparam[0] = &handle; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCDL_CLOSE, "s", inparam, NULL, outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_dlsend: Enva un mensaje por medio de la capa de enlace del modem PLC. */ size_t modplc_dlsend(modplc_hd *hd, int handle, modplc_dlphyaddr addr, unsigned char prio, const void *msg, size_t msgsize) { /* Variables. */ void *inparam[4]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

"b",

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0; /* Enva un mensaje. */ inparam[0] = &handle; inparam[1] = addr; inparam[2] = &prio; inparam[3] = &msgsize; outparam[0] = &msgsize; if (__modplc_sendcmd__(hd, MODPLCDL_SEND, "sabs", inparam, msg, outparam, NULL)) return msgsize; return 0; } /* Funcin modplc_dlreceive: Recibe un mensaje por medio de la capa de enlace del modem PLC. */ size_t modplc_dlreceive(modplc_hd *hd, int handle, modplc_dlphyaddr addr, void *msg, size_t msgsize) { /* Variables. */ void *inparam[2]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

"s",

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0; /* Recibe un mensaje. */ inparam[0] = &handle; inparam[1] = &msgsize; outparam[0] = addr; outparam[1] = &msgsize; if (__modplc_sendcmd__(hd, MODPLCDL_RECEIVE, "ss", inparam, NULL, outparam, msg)) return msgsize; return 0;

"as",

FernandoArielBeunza79156

389

Tesis de Grado en Ingeniera Informtica


} /* Funcin modplc_dlpoll: Verifica la llegada de un nuevo mensaje por medio de la capa de enlace del modem PLC. */ int modplc_dlpoll(modplc_hd *hd, int handle) { /* Variables. */ unsigned char result; void *inparam[1]; void *outparam[1];

/* Resultado del comando. */ /* Parmetros de entrada del comando. */ /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0; /* Verifica la llegada de un nuevo mensaje. */ inparam[0] = &handle; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCDL_POLL, "s", inparam, NULL, outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_dlgetaddress: Devuelve la direccin fsica de la capa de enlace del modem PLC. */ int modplc_dlgetaddress(modplc_hd *hd, unsigned char iface, modplc_dlphyaddr paddr) { /* Variables. */ void *inparam[1]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

"b",

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0; /* Devuelve la direccin fsica. */ inparam[0] = &iface; outparam[0] = paddr; return __modplc_sendcmd__(hd, MODPLCDL_GETADDRESS, "b", inparam, NULL, "a", outparam, NULL); } /* Funcin modplc_dladdlogaddress: Agrega una nueva direccin lgica a la capa de enlace del modem PLC. */ int modplc_dladdlogaddress(modplc_hd *hd, unsigned char iface, unsigned char prot, modplc_dllogaddr laddr) { /* Variables. */ unsigned char result; /* Resultado del comando. */ void *inparam[3]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del

390

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0; /* Agrega una nueva direccin lgica. */ inparam[0] = &iface; inparam[1] = &prot; inparam[2] = &laddr; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCDL_ADDLOGADDRESS, "bbl", inparam, NULL, "b", outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_dldellogaddress: Elimina una direccin lgica a la capa de enlace del modem PLC. */ int modplc_dldellogaddress(modplc_hd *hd, unsigned char iface, unsigned char prot, modplc_dllogaddr laddr) { /* Variables. */ unsigned char result; /* Resultado del comando. */ void *inparam[3]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0; /* Elimina una direccin lgica. */ inparam[0] = &iface; inparam[1] = &prot; inparam[2] = &laddr; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCDL_DELLOGADDRESS, "bbl", inparam, NULL, "b", outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_dlgetphyaddress: Devuelve la direccin fsica asociada a la direccin lgica de la capa de enlace del modem PLC. */ int modplc_dlgetphyaddress(modplc_hd *hd, unsigned char iface, unsigned char prot, modplc_dllogaddr laddr, modplc_dlphyaddr paddr) { /* Variables. */ void *inparam[3]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0;

FernandoArielBeunza79156

391

Tesis de Grado en Ingeniera Informtica


/* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0; /* Devuelve la direccin fsica asociada a la direccin lgica. */ inparam[0] = &iface; inparam[1] = &prot; inparam[2] = &laddr; outparam[0] = paddr; return __modplc_sendcmd__(hd, MODPLCDL_GETPHYADDRESS, "bbl", inparam, NULL, "a", outparam, NULL); } /* Funcin modplc_dlgetpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de enlace del modem PLC. */ size_t modplc_dlgetpayloadsize(modplc_hd *hd, unsigned char iface) { /* Variables. */ unsigned short int payloadsize; /* Cantidad mxima de bytes que puede contener una trama. */ void *inparam[1]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0; /* Devuelve la cantidad mxima de byes que puede contener un mensaje. */ inparam[0] = &iface; outparam[0] = &payloadsize; if (__modplc_sendcmd__(hd, MODPLCDL_GETPAYLOADSIZE, "b", inparam, NULL, "s", outparam, NULL)) return (size_t) payloadsize; return 0; } /* Funcin modplc_sppublish: Registra el dispositivo como publicador del grupo de difusin especificado de la capa de sesin del modem PLC. */ int modplc_sppublish(modplc_hd *hd, modplc_spgrpid grpid) { /* Variables. */ unsigned char result; void *inparam[1]; void *outparam[1];

/* Resultado del comando. */ /* Parmetros de entrada del comando. */ /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de sesin. */ if (hd->layer != MODPLC_SESSIONLAYER) return 0; /* Registra el dispositivo como publicador del grupo de difusin especificado. */ inparam[0] = &grpid; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCSP_PUBLISH, "b", inparam, NULL, outparam, NULL)) return (result == 1);

"b",

392

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


return 0; } /* Funcin modplc_spsubscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado de la capa de sesin del modem PLC. */ int modplc_spsubscribe(modplc_hd *hd, modplc_spgrpid grpid) { /* Variables. */ unsigned char result; /* Resultado del comando. */ void *inparam[1]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de sesin. */ if (hd->layer != MODPLC_SESSIONLAYER) return 0; /* Registra el dispositivo como suscriptor del grupo de difusin especificado. */ inparam[0] = &grpid; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCSP_SUBSCRIBE, "b", inparam, NULL, outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_spleave: Desvincula el dispositivo del grupo de difusin especificado de la capa de sesin del modem PLC. */ int modplc_spleave(modplc_hd *hd, modplc_spgrpid grpid) { /* Variables. */ unsigned char result; void *inparam[1]; void *outparam[1];

"b",

/* Resultado del comando. */ /* Parmetros de entrada del comando. */ /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de sesin. */ if (hd->layer != MODPLC_SESSIONLAYER) return 0; /* Desvincula el dispositivo del grupo de difusin especificado. */ inparam[0] = &grpid; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCSP_LEAVE, "b", inparam, NULL, "b", outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_spsend: Enva un mensaje por medio de la capa de sesin del modem PLC. */ size_t modplc_spsend(modplc_hd *hd, modplc_spgrpid grpid, int nosec, const void *msg, size_t msgsize) {

FernandoArielBeunza79156

393

Tesis de Grado en Ingeniera Informtica


/* Variables. */ void *inparam[3]; void *outparam[1]; /* Parmetros de entrada del comando. */ /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de sesin. */ if (hd->layer != MODPLC_SESSIONLAYER) return 0; /* Enva un mensaje. */ inparam[0] = &grpid; inparam[1] = &nosec; inparam[2] = &msgsize; outparam[0] = &msgsize; if (__modplc_sendcmd__(hd, MODPLCSP_SEND, "bbs", inparam, msg, outparam, NULL)) return msgsize; return 0; } /* Funcin modplc_spreceive: Recibe un mensaje por medio de la capa de sesin del modem PLC. */ size_t modplc_spreceive(modplc_hd *hd, modplc_spgrpid *grpid, void *msg, size_t msgsize) { /* Variables. */ void *inparam[1]; /* Parmetros de entrada del comando. */ void *outparam[2]; /* Parmetros de salida del comando. */

"s",

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de sesin. */ if (hd->layer != MODPLC_SESSIONLAYER) return 0; /* Recibe un mensaje. */ inparam[0] = &msgsize; outparam[0] = grpid; outparam[1] = &msgsize; if (__modplc_sendcmd__(hd, MODPLCSP_RECEIVE, "s", inparam, NULL, outparam, msg)) return msgsize; return 0; } /* Funcin modplc_sppoll: Verifica la llegada de un nuevo mensaje por medio de la capa de sesin del modem PLC. */ int modplc_sppoll(modplc_hd *hd) { /* Variables. */ unsigned char result; void *outparam[1];

"bs",

/* Resultado del comando. */ /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de sesin. */

394

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


if (hd->layer != MODPLC_SESSIONLAYER) return 0; /* Verifica la llegada de un nuevo mensaje. */ outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCSP_POLL, "", NULL, NULL, NULL)) return (result == 1); return 0; } /* Funcin modplc_spgetpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de sesin del modem PLC. */ size_t modplc_spgetpayloadsize(modplc_hd *hd) { /* Variables. */ unsigned short int payloadsize; void *outparam[1];

"b", outparam,

/* Cantidad mxima de bytes que puede contener una trama. */ /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de sesin. */ if (hd->layer != MODPLC_SESSIONLAYER) return 0; /* Devuelve la cantidad mxima de byes que puede contener un mensaje. */ outparam[0] = &payloadsize; if (__modplc_sendcmd__(hd, MODPLCSP_GETPAYLOADSIZE, "", NULL, NULL, "s", outparam, NULL)) return (size_t) payloadsize; return 0; }

/* Implementacin de funciones privadas. */ /* Funcin __modplc_sendcmdline__: Enva una lnea de comando por medio de la interfaz de comunicacin por puerto serie. */ static char __modplc_sendcmdline__(modplc_hd *hd, const char *cmdline, char *resp, size_t respsize) { /* Variables. */ size_t send; /* Cantidad de bytes por envo. */ size_t size; /* Tamao de la lnea de respuesta. */ char *lastchar; /* Pntero al ltimo caracter. */ char respline[MODPLC_BUFFERSIZE]; /* Respuesta a la lnea de comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Recibe la respuesta al comando. */ size = 0; *respline = 0; while(size < respsize) { /* Enva un fragmento de la lnea de comando. */ send = strlen(cmdline) - size; if (send > MODPLC_FRAGMENTLINESIZE) send = MODPLC_FRAGMENTLINESIZE; if (size < strlen(cmdline)) serial_send(hd->serialhd, cmdline + size, send);

FernandoArielBeunza79156

395

Tesis de Grado en Ingeniera Informtica


/* Recibe la respuesta. */ size += serial_receive(hd->serialhd, respline + size, respsize - size); *(respline + size) = 0; /* Verifica si se recibi el smbolo de la lnea de comando. */ lastchar = strchr(respline, MODPLC_INITPROMPT); if (lastchar) break; lastchar = strchr(respline, MODPLC_LAYPROMPT); if (lastchar) break; lastchar = strchr(respline, MODPLC_NORMPROMPT); if (lastchar) break; lastchar = strchr(respline, MODPLC_PARAMPROMPT); if (lastchar) break; if (size > respsize) { lastchar = respline + size - 1; break; } } /* Devuelve la respuesta al comando. */ if (resp) strcpy(resp, respline); if (hd->debugmode && size) { printf("%s", respline); fflush(stdout); } return *lastchar; } /* Funcin __modplc_sendcmd__: Enva un comando por medio de la interfaz de comunicacin por puerto serie y devuelve su respuesta . */ static int __modplc_sendcmd__(modplc_hd *hd, char op, const char *infmt, void **inparam, const void *inframe, const char *outfmt, void **outparam, void *outframe) { /* Variables. */ int param; /* Nmero de parmetro. */ size_t i; /* Contador. */ size_t j; /* Contador. */ size_t framesize; /* Tamao de la trama. */ unsigned char *ptrline; /* Puntero a la lnea de respuesta de comando. */ unsigned char *ptrparam; /* Puntero al parmetro. */ unsigned char *ptrresp; /* Puntero a la respuesta. */ unsigned char *ptrframe; /* Puntero a la trama. */ unsigned char dat; /* Dato. */ char hexval[3]; /* Valor hexadecimal. */ char cmdline[MODPLC_BUFFERSIZE]; /* Lnea de comando. */ char rline[MODPLC_BUFFERSIZE]; /* Lnea de respuesta de comando. */ char respline[MODPLC_BUFFERSIZE]; /* Lnea de respuesta de comando. */

/* Verifica que el modem PLC se encuentre en estado activo. */ modplc_status(hd); if (!hd->status) return 0; /* Enva el param = 0; *(cmdline + *(cmdline + *(cmdline + while(infmt { comando y sus parmetros. */ 0) 1) 2) && = op; = '\n'; = 0; inparam)

396

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Enva el comando y un parmetro procesado. */ if (!infmt[param]) break; if (__modplc_sendcmdline__(hd, cmdline, cmdline, MODPLC_BUFFERSIZE) != MODPLC_PARAMPROMPT) return 0; /* Procesa el siguiente parmetro a enviar. */ ptrparam = (unsigned char *) inparam[param]; if (infmt[param] == 'b') sprintf(cmdline, "\\%02X\n", *((unsigned char *) inparam[param])); else if (infmt[param] == 's') sprintf(cmdline, "\\%02X\\%02X\n", ptrparam[1], ptrparam[0]); else if (infmt[param] == 'l') sprintf(cmdline, "\\%02X\\%02X\\%02X\\%02X\n", ptrparam[3], ptrparam[2], ptrparam[1], ptrparam[0]); else if (infmt[param] == 'a') sprintf(cmdline, "\\%02X\\%02X\\%02X\\%02X\\%02X\\%02X\\%02X\\%02X\n", ptrparam[0], ptrparam[1], ptrparam[2], ptrparam[3], ptrparam[4], ptrparam[5], ptrparam[6], ptrparam[7]); param ++; } /* Si hay una trama que enviar se enva su contenido. */ if (inframe) { /* Espera para poder enviar la trama. */ if (__modplc_sendcmdline__(hd, cmdline, respline, MODPLC_BUFFERSIZE) != MODPLC_PARAMPROMPT) return 0; /* Enva la trama. */ *cmdline = 0; ptrframe = (char *) inframe; framesize = *((size_t *) inparam[param - 1]); for(i = 0; i < framesize; ) { dat = (unsigned char) *ptrframe; if ((dat >= 0x20) && (dat <= 0x7e) && (dat != '\\') && (dat != MODPLC_INITPROMPT) && (dat != MODPLC_LAYPROMPT) && (dat != MODPLC_NORMPROMPT) && (dat != MODPLC_PARAMPROMPT)) sprintf(hexval, "%c", dat); else sprintf(hexval, "\\%02X", dat); strcat(cmdline, hexval); ptrframe ++; i ++; if ((i % 24) && (i < framesize)) continue; strcat(cmdline, "\n"); if (__modplc_sendcmdline__(hd, cmdline, respline, MODPLC_BUFFERSIZE) != MODPLC_PARAMPROMPT) break; *cmdline = 0; } } /* Caso contrario se espera la respuesta al comando. */ else { if (__modplc_sendcmdline__(hd, cmdline, respline, MODPLC_BUFFERSIZE) != MODPLC_NORMPROMPT) return 0; } /* Recibe los parmetros de respuesta. */ i = 0; param = 0; ptrresp = respline; while(*ptrresp != MODPLC_NORMPROMPT) {

FernandoArielBeunza79156

397

Tesis de Grado en Ingeniera Informtica


if (*ptrresp == '\r') { ptrresp ++; continue; } else if (*ptrresp != '\n') { rline[i++] = *(ptrresp ++); continue; } rline[i] = 0; ptrresp ++; i = 0; if (!strlen(rline)) continue; if (param < 1) { param ++; continue; } if (!outfmt[param - 1]) { ptrresp -= (strlen(rline) + 2); break; } ptrline = rline; ptrparam = (unsigned char *) outparam[param - 1]; if (outfmt[param - 1] == 'b') { if (*ptrline != '\\') *ptrparam = *(ptrline ++); else { ptrline ++; hexval[0] = *(ptrline ++); hexval[1] = *(ptrline ++); hexval[2] = 0; sscanf(hexval, "%X", &dat); *ptrparam = dat; } } else if (outfmt[param - 1] == 's') { for(j = 0; j < 2; j++) { if (*ptrline != '\\') *(ptrparam + 1 - j) = *(ptrline ++); else { ptrline ++; hexval[0] = *(ptrline ++); hexval[1] = *(ptrline ++); hexval[2] = 0; sscanf(hexval, "%X", &dat); *(ptrparam + 1 - j) = dat; } } } else if (outfmt[param - 1] == 'l') { for(j = 0; j < 4; j++) { if (*ptrline != '\\') *(ptrparam + 3 - j) = *(ptrline ++); else { ptrline ++; hexval[0] = *(ptrline ++); hexval[1] = *(ptrline ++); hexval[2] = 0; sscanf(hexval, "%X", &dat); *(ptrparam + 3 - j) = dat;

398

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


} } } else if (outfmt[param - 1] == 'a') { for(j = 0; j < 8; j++) { if (*ptrline != '\\') *(ptrparam + j) = *(ptrline ++); else { ptrline ++; hexval[0] = *(ptrline ++); hexval[1] = *(ptrline ++); hexval[2] = 0; sscanf(hexval, "%X", &dat); *(ptrparam + j) = dat; } } } param++; } /* Si hay una trama que recibir se recibe su contenido. */ if (outframe) { ptrframe = (char *) outframe; framesize = *((size_t *) outparam[param - 2]); for(j = 0; j < framesize; ) { dat = *(ptrresp ++); if ((dat == '\n') || (dat == '\r')) continue; if (dat != '\\') *ptrframe = dat; else { hexval[0] = *(ptrresp ++); hexval[1] = *(ptrresp ++); hexval[2] = 0; sscanf(hexval, "%X", &dat); *ptrframe = dat; } ptrframe ++; j ++; } } /* xito. */ return 1; }

C.3.4.6. Archivo modsp.h


/* modsp.h: Declaracin de funciones referentes a la interfaz de la capa de sesin del modem PLC. */

#if !defined(__MODSP_H__) #define __MODSP_H__

/* Archivos includos necesarios. */ #include "config.h" #include "modplc.h"

FernandoArielBeunza79156

399

Tesis de Grado en Ingeniera Informtica

/* Definicin de tipos. */ /* Identificador de grupo. */ typedef unsigned char modsp_grpid; /* Manejador de interfaz con la capa de sesin del modem PLC. */ typedef struct { HANDLE mutexsem; /* Semforo de finalizacin de deteccin de recepcin. */ HANDLE detectthread; /* Manejador de hilo de deteccin de recepcin. */ size_t payloadsize; /* Cantidad mxima de bytes que puede contener un mensaje. */ modplc_hd *modplchd; /* Manejador de interfaz con el modem PLC. */ void (*recfun) (void *, modsp_grpid, void *, size_t, void *); /* Funcin manejadora de mensajes recibidos. */ void *param; /* Parmetros para la funcin manejadora de mensajes recibidos. */ } modsp_hd;

/* Declaracin de funciones pblicas. */ /* Funcin modsp_init: Inicializa los recursos utilizados por la capa de sesin del modem PLC. */ modsp_hd *modsp_init(int, int); /* Funcin modsp_release: Libera los recursos utilizados por la capa de sesin del modem PLC. */ int modsp_release(modsp_hd *); /* Funcin modsp_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ int modsp_publish(modsp_hd *, modsp_grpid); /* Funcin modsp_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ int modsp_subscribe(modsp_hd *, modsp_grpid); /* Funcin modsp_leave: Desvincula el dispositivo del grupo de difusin especificado. */ int modsp_leave(modsp_hd *, modsp_grpid); /* Funcin modsp_send: Enva un mensaje por medio de la capa de sesin del modem PLC. */ size_t modsp_send(modsp_hd *, modsp_grpid, unsigned char, const void *, size_t); /* Funcin modsp_receive: Recibe un mensaje por medio de la capa de sesin del modem PLC. */

400

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


size_t modsp_receive(modsp_hd *, modsp_grpid *, void *, size_t); /* Funcin modsp_notify: Define una funcin manejadora de mensajes recibidos. */ int modsp_notify(modsp_hd *, void (*func)(modsp_hd *, modsp_grpid, void *, size_t, void *), void *); /* Funcin modsp_poll: Verifica la llegada de un nuevo mensaje. */ int modsp_poll(modsp_hd *); /* Funcin modsp_status: Devuelve el estado del modem PLC. */ int modsp_status(modsp_hd *); /* Funcin modsp_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de sesin del modem PLC. */ size_t modsp_getpayloadsize(modsp_hd *);

#endif

C.3.4.7. Archivo modsp.c


/* modsp.c: Implementacin de funciones referentes a la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <windows.h> #include <process.h> #include "modplc.h" #include "modsp.h"

/* Declaracin de funciones privadas. */ static DWORD WINAPI __modsp_detectproc__(LPVOID);

/* Implementacin de funciones pblicas. */ /* Funcin modsp_init: Inicializa los recursos utilizados por la capa de sesin del modem PLC. */ modsp_hd *modsp_init(int sid, int debugmode) { /* Variables. */ modsp_hd *handle;

/* Manejador de interfaz con la capa de sesin del modem PLC. */

/* Crea un nuevo manejador de interfaz con la capa de sesin del modem PLC. */ handle = (modsp_hd *) malloc(sizeof(modsp_hd));

FernandoArielBeunza79156

401

Tesis de Grado en Ingeniera Informtica


if (!handle) return NULL; /* Inicializa el manejador de interfaz con la capa de sesin del modem PLC. */ while(1) { /* Inicializa el manejador de interfaz con el modem PLC. */ handle->modplchd = modplc_init(sid, MODPLC_SESSIONLAYER, debugmode); if (!handle->modplchd) break; /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ handle->payloadsize = modplc_spgetpayloadsize(handle->modplchd); if (!handle->payloadsize) break; /* Inicializa el manejador de mensajes recibidos. */ handle->param = NULL; handle->recfun = NULL; /* Inicializa semforo. */ handle->mutexsem = CreateSemaphore(NULL, 1, 1, NULL); if (handle->mutexsem == INVALID_HANDLE_VALUE) break; /* Devuelve el manejador creado. */ return handle; } /* No se pudo inicializar la interfaz con la capa de sesin del modem PLC. */ modplc_release(handle->modplchd); free(handle); return NULL; } /* Funcin modsp_release: Libera los recursos utilizados por la capa de sesin del modem PLC. */ int modsp_release(modsp_hd *hd) { /* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Libera el manejador de mensajes recibidos. */ modsp_notify(hd, NULL, NULL); /* Libera la interfaz con el modem PLC. */ modplc_release(hd->modplchd); /* Libera los recursos utilizados por la interfaz con la capa de sesin del modem PLC. */ CloseHandle(hd->mutexsem); free(hd); /* xito. */ return 1; } /* Funcin modsp_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ int modsp_publish(modsp_hd *hd, modsp_grpid grpid) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */

402

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Registra el dispositivo como publicador. */ result = modplc_sppublish(hd->modplchd, grpid); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve el resultado del registro del dispositivo. */ return result; } /* Funcin modsp_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ int modsp_subscribe(modsp_hd *hd, modsp_grpid grpid) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Registra el dispositivo como suscriptor. */ result = modplc_spsubscribe(hd->modplchd, grpid); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve el resultado del registro del dispositivo. */ return result; } /* Funcin modsp_leave: Desvincula el dispositivo del grupo de difusin especificado. */ int modsp_leave(modsp_hd *hd, modsp_grpid grpid) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Desvincula el dispositivo. */ result = modplc_spleave(hd->modplchd, grpid); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve el resultado de la desvinculacin del dispositivo. */ return result; } /* Funcin modsp_send:

FernandoArielBeunza79156

403

Tesis de Grado en Ingeniera Informtica


Enva un mensaje por medio de la capa de sesin del modem PLC. */ size_t modsp_send(modsp_hd *hd, modsp_grpid grpid, unsigned char nosec, const void *msg, size_t msgsize) { /* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Enva un mensaje. */ msgsize = modplc_spsend(hd->modplchd, grpid, nosec, msg, msgsize); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve la cantidad de bytes envados. */ return msgsize; } /* Funcin modsp_receive: Recibe un mensaje por medio de la capa de sesin del modem PLC. */ size_t modsp_receive(modsp_hd *hd, modsp_grpid *grpid, void *msg, size_t msgsize) { /* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera la llegada de un mensaje. */ while(!modsp_poll(hd)); /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Recibe un mensaje. */ msgsize = modplc_spreceive(hd->modplchd, grpid, msg, msgsize); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve la cantidad de bytes recibidos. */ return msgsize; } /* Funcin modsp_notify: Define una funcin manejadora de mensajes recibidos. */ int modsp_notify(modsp_hd *hd, void (*func)(modsp_hd *, modsp_grpid, void *, size_t, void *), void *param) { /* Variables. */ DWORD tid; /* Identificador de hilo. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Si la funcin manejadora es nula y no hay ninguna funcin manejadora definida previamente no se hace nada. */ if ((!func) && (!hd->recfun)) return 1; /* Si la funcin manejadora no es nula y hay una funcin manejadora previamente definida actualiza la funcin manejadora. */ if ((func) && (hd->recfun))

404

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


{ WaitForSingleObject(hd->mutexsem, INFINITE); hd->recfun = func; hd->param = param; ReleaseSemaphore(hd->mutexsem, 1, NULL); return 1; } /* Si la funcin manejadora es nula y hay una funcin manejadora definida previamente se elimina esta ltima. */ if ((!func) && (hd->recfun)) { WaitForSingleObject(hd->mutexsem, INFINITE); hd->recfun = NULL; hd->param = param; ReleaseSemaphore(hd->mutexsem, 1, NULL); WaitForSingleObject(hd->detectthread, INFINITE); return 1; } /* Si la funcin manejadora no es nula y no hay una funcin manejadora previamente definida se define la nueva funcin manejadora. */ if ((func) && (!hd->recfun)) { WaitForSingleObject(hd->mutexsem, INFINITE); hd->recfun = func; hd->param = param; hd->detectthread = CreateThread(NULL, 0, __modsp_detectproc__, hd, 0, &tid); if (hd->detectthread == INVALID_HANDLE_VALUE) { hd->recfun = NULL; hd->param = NULL; ReleaseSemaphore(hd->mutexsem, 1, NULL); return 0; } ReleaseSemaphore(hd->mutexsem, 1, NULL); return 1; } /* No se pudo definir la funcin manejadora de mensajes recibidos. */ return 0; } /* Funcin modsp_poll: Verifica la llegada de un nuevo mensaje. */ int modsp_poll(modsp_hd *hd) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Verifica la recepcin de un mensaje. */ result = modplc_sppoll(hd->modplchd); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve el resultado de la verificacin de la recepcin de un mensaje. */ return result; }

FernandoArielBeunza79156

405

Tesis de Grado en Ingeniera Informtica


/* Funcin modsp_status: Devuelve el estado del modem PLC. */ int modsp_status(modsp_hd *hd) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Obtiene el estado del modem PLC. */ result = modplc_status(hd->modplchd); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve el resultado del modem PLC. */ return result; } /* Funcin modsp_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de sesin del modem PLC. */ size_t modsp_getpayloadsize(modsp_hd *hd) { /* Variables. */ size_t payloadsize;

/* Cantidad mxima de bytes que puede contener un mensaje. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ payloadsize = modplc_spgetpayloadsize(hd->modplchd); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve la cantidad mxima de bytes que puede contener un mensaje. */ return payloadsize; }

/* Implementacin de funciones privadas. */ /* Funcin __modsp_detectproc__: Verifica la existencia de un mensaje recibido disponible para ser ledo. */ static DWORD WINAPI __modsp_detectproc__(LPVOID param) { /* Variables. */ int recvflag; size_t msgsize; modsp_grpid grpid;

/* Indicador de recepcin de un mensaje. */ /* Tamao del mensaje recibido. */ /* Identificador de grupo. */

406

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


modsp_hd *hd; void (*func) (void *, modsp_grpid, void *, size_t, void *); char *msg; /* Manejador de interfaz con la capa de sesin del modem PLC. */

/* Manejador de mensajes recibidos. */ /* Puntero al mensaje recibido. */

/* Carga el manejador de interfaz con la capa de sesin del modem PLC. */ hd = (modsp_hd *) param; /* Verifica la existencia de un mensaje recibido. */ while(1) { /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Verifica la recepcin de un mensaje. */ func = hd->recfun; if (!func) break; recvflag = modplc_sppoll(hd->modplchd); if (recvflag) { msg = (unsigned char *) malloc(hd->payloadsize * sizeof(unsigned char)); if (msg) msgsize = modplc_spreceive(hd->modplchd, &grpid, msg, hd->payloadsize); else recvflag = 0; } /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Verifica si se ha detectado la recepcin de un mensaje para invocar a la funcin manejadora de mensajes recibidos. */ if (recvflag) { func(hd, grpid, msg, msgsize, hd->param); free(msg); } } /* Fin de ejecucin del hilo de deteccin de recepcin. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); return 0; }

C.3.4.8. Archivo moddl.h


/* moddl.h: Declaracin de funciones referentes a la interfaz de la capa de enlace del modem PLC. */

#if !defined(__MODDL_H__) #define __MODDL_H__

/* Archivos includos necesarios. */ #include "config.h" #include "modplc.h"

FernandoArielBeunza79156

407

Tesis de Grado en Ingeniera Informtica


/* Definicin de tipos. */ /* Direccin fsica del modem PLC. */ typedef unsigned char moddl_phyaddr[8]; /* Direccin lgica del modem PLC. */ typedef unsigned long int moddl_logaddr; /* Manejador de interfaz con la capa de enlace del modem PLC. */ typedef struct { HANDLE mutexsem; /* Semforo de finalizacin de deteccin de recepcin. */ unsigned long int conncounter; /* Contador de conexiones abiertas. */ modplc_hd *modplchd; /* Manejador de interfaz con el modem PLC. */ } moddl_hd; /* Manejador de conexin por medio de la capa de enlace del modem PLC. */ typedef struct { HANDLE detectthread; /* Manejador de hilo de deteccin de recepcin. */ int handle; /* Identificador de conexin. */ size_t payloadsize; /* Cantidad mxima de bytes que puede contener un mensaje. */ unsigned char iface; /* Identificador de intarfaz fsica. */ moddl_hd *moddlhd; /* Manejador de interfaz con la capa de enlance del modem PLC. */ void (*recfun) (void *, moddl_phyaddr, void *, size_t, void *); /* Funcin manejadora de mensajes recibidos. */ void *param; /* Parmetros para la funcin manejadora de mensajes recibidos. */ } moddlconn_hd;

/* Declaracin de funciones pblicas. */ /* Funcin moddl_init: Inicializa los recursos utilizados por la capa de enlace del modem PLC. */ moddl_hd *moddl_init(int, int); /* Funcin moddl_release: Libera los recursos utilizados por la capa de enlace del modem PLC. */ int moddl_release(moddl_hd *); /* Funcin moddl_open: Abre una conexin por medio de la capa de enlace del modem PLC. */ moddlconn_hd *moddl_open(moddl_hd *, unsigned char, unsigned char); /* Funcin moddl_close: Cierra una conexin por medio de la capa de enlace del modem PLC. */ int moddl_close(moddlconn_hd *); /* Funcin moddl_send:

408

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Enva un mensaje por medio de la capa de enlace del modem PLC. */ size_t moddl_send(moddlconn_hd *, moddl_phyaddr, unsigned char, const void *, size_t); /* Funcin moddl_receive: Recibe un mensaje por medio de la capa de enlace del modem PLC. */ size_t moddl_receive(moddlconn_hd *, moddl_phyaddr, void *, size_t); /* Funcin moddl_notify: Define una funcin manejadora de mensajes recibidos. */ int moddl_notify(moddlconn_hd *, void (*func)(moddlconn_hd *, moddl_phyaddr, void *, size_t, void *), void *); /* Funcin modsp_poll: Verifica la llegada de un nuevo mensaje. */ int moddl_poll(moddlconn_hd *); /* Funcin moddl_getaddress: Devuelve la direccin fsica de la capa de enlace del modem PLC. */ int moddl_getaddress(moddl_hd *, unsigned char, moddl_phyaddr); /* Funcin moddl_addlogaddress: Agrega una nueva direccin lgica a la capa de enlade del modem PLC. */ int moddl_addlogaddress(moddl_hd *, unsigned char, unsigned char, moddl_logaddr); /* Funcin moddl_dellogaddress: Elimina una direccin lgica a la capa de enlace del modem PLC. */ int moddl_dellogaddress(moddl_hd *, unsigned char, unsigned char, moddl_logaddr); /* Funcin moddl_getphyaddress: Devuelve la direccin fsica asociada a la direccin lgica de la capa de enlace del modem PLC. */ int moddl_getphyaddress(moddl_hd *, unsigned char, unsigned char, moddl_logaddr, moddl_phyaddr); /* Funcin moddl_status: Devuelve el estado del modem PLC. */ int moddl_status(moddl_hd *); /* Funcin moddl_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de enlace del modem PLC. */ size_t moddl_getpayloadsize(moddl_hd *, unsigned char);

#endif

FernandoArielBeunza79156

409

Tesis de Grado en Ingeniera Informtica

C.3.4.9. Archivo moddl.c


/* moddl.c: Implementacin de funciones referentes a la interfaz de la capa de enlace del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <windows.h> #include <process.h> #include "modplc.h" #include "moddl.h"

/* Declaracin de funciones privadas. */ static DWORD WINAPI __moddl_detectproc__(LPVOID);

/* Implementacin de funciones pblicas. */ /* Funcin moddl_init: Inicializa los recursos utilizados por la capa de enlace del modem PLC. */ moddl_hd *moddl_init(int sid, int debugmode) { /* Variables. */ moddl_hd *handle;

/* Manejador de interfaz con la capa de enlace del modem PLC. */

/* Crea un nuevo manejador de interfaz con la capa de enlace del modem PLC. */ handle = (moddl_hd *) malloc(sizeof(moddl_hd)); if (!handle) return NULL; /* Inicializa el manejador de interfaz con la capa de enlace del modem PLC. */ while(1) { /* Inicializa el manejador de interfaz con el modem PLC. */ handle->modplchd = modplc_init(sid, MODPLC_DATALINKLAYER, debugmode); if (!handle->modplchd) break; /* Inicializa el contador de conexiones abiertas. */ handle->conncounter = 0; /* Inicializa semforo. */ handle->mutexsem = CreateSemaphore(NULL, 1, 1, NULL); if (handle->mutexsem == INVALID_HANDLE_VALUE) break; /* Devuelve el manejador creado. */ return handle; } /* No se pudo inicializar la interfaz con la capa de enlace del modem PLC. */ modplc_release(handle->modplchd); free(handle); return NULL; } /* Funcin moddl_release: Libera los recursos utilizados por la capa de enlace del modem PLC. */ int moddl_release(moddl_hd *hd)

410

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


{ /* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Verifica que no existan conexiones abiertas. */ if (hd->conncounter) return 0; /* Libera la interfaz con el modem PLC. */ modplc_release(hd->modplchd); /* Libera los recursos utilizados por la interfaz con la capa de enlace del modem PLC. */ CloseHandle(hd->mutexsem); free(hd); /* xito. */ return 1; } /* Funcin moddl_open: Abre una conexin por medio de la capa de enlace del modem PLC. */ moddlconn_hd *moddl_open(moddl_hd *hd, unsigned char iface, unsigned char prot) { /* Variables. */ moddlconn_hd *handle; /* Manejador de conexin de la capa de enlace del modem PLC. */

/* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return NULL; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Crea un nuevo manejador de conexin por medio de la capa de enlace del modem PLC. */ handle = (moddlconn_hd *) malloc(sizeof(moddlconn_hd)); if (!handle) { ReleaseSemaphore(hd->mutexsem, 1, NULL); return NULL; } /* Inicializa el manejador de conexin. */ while(1) { /* Abre una conexin. */ handle->moddlhd = hd; handle->iface = iface; handle->handle = modplc_dlopen(hd->modplchd, handle->iface, prot); if (!handle->handle) break; /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ handle->payloadsize = modplc_dlgetpayloadsize(hd->modplchd, iface); if (!handle->payloadsize) break; /* Inicializa el manejador de mensajes recibidos. */ handle->param = NULL; handle->recfun = NULL; /* Actualiza el nmero de conexiones. */ handle->moddlhd->conncounter ++; /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL);

FernandoArielBeunza79156

411

Tesis de Grado en Ingeniera Informtica


/* Devuelve el manejador creado. */ return handle; } /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* No se pudo abrir la conexin. */ modplc_dlclose(hd->modplchd, handle->handle); free(handle); return NULL; } /* Funcin moddl_close: Cierra una conexin por medio de la capa de enlace del modem PLC. */ int moddl_close(moddlconn_hd *hd) { /* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Libera el manejador de mensajes recibidos. */ moddl_notify(hd, NULL, NULL); /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->moddlhd->mutexsem, INFINITE); /* Actualiza el nmero de conexiones. */ hd->moddlhd->conncounter --; /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->moddlhd->mutexsem, 1, NULL); /* Libera los recursos utilizados por la conexin por medio de la capa de enlace del modem PLC. */ free(hd); /* xito. */ return 1; } /* Funcin moddl_send: Enva un mensaje por medio de la capa de enlace del modem PLC. */ size_t moddl_send(moddlconn_hd *hd, moddl_phyaddr addr, unsigned char prio, const void *msg, size_t msgsize) { /* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->moddlhd->mutexsem, INFINITE); /* Enva un mensaje. */ msgsize = modplc_dlsend(hd->moddlhd->modplchd, hd->handle, addr, prio, msg, msgsize); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->moddlhd->mutexsem, 1, NULL); /* Devuelve la cantidad de bytes recibidos. */ return msgsize; } /* Funcin moddl_receive: Recibe un mensaje por medio de la capa de enlace del modem PLC.

412

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


*/ size_t moddl_receive(moddlconn_hd *hd, moddl_phyaddr addr, void *msg, size_t msgsize) { /* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera la llegada de un mensaje. */ while(!moddl_poll(hd)); /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->moddlhd->mutexsem, INFINITE); /* Recibe un mensaje. */ msgsize = modplc_dlreceive(hd->moddlhd->modplchd, hd->handle, addr, msg, msgsize); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->moddlhd->mutexsem, 1, NULL); /* Devuelve la cantidad de bytes recibidos. */ return msgsize; } /* Funcin moddl_notify: Define una funcin manejadora de mensajes recibidos. */ int moddl_notify(moddlconn_hd *hd, void (*func)(moddlconn_hd *, moddl_phyaddr, void *, size_t, void *), void *param) { /* Variables. */ DWORD tid; /* Identificador de hilo. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Si la funcin manejadora es nula y no hay ninguna funcin manejadora definida previamente no se hace nada. */ if ((!func) && (!hd->recfun)) return 1; /* Si la funcin manejadora no es nula y hay una funcin manejadora previamente definida actualiza la funcin manejadora. */ if ((func) && (hd->recfun)) { WaitForSingleObject(hd->moddlhd->mutexsem, INFINITE); hd->recfun = func; hd->param = param; ReleaseSemaphore(hd->moddlhd->mutexsem, 1, NULL); return 1; } /* Si la funcin manejadora es nula y hay una funcin manejadora definida previamente se elimina esta ltima. */ if ((!func) && (hd->recfun)) { WaitForSingleObject(hd->moddlhd->mutexsem, INFINITE); hd->recfun = NULL; hd->param = param; ReleaseSemaphore(hd->moddlhd->mutexsem, 1, NULL); WaitForSingleObject(hd->detectthread, INFINITE); return 1; } /* Si la funcin manejadora no es nula y no hay una funcin manejadora previamente definida se define la nueva funcin manejadora. */ if ((func) && (!hd->recfun)) {

FernandoArielBeunza79156

413

Tesis de Grado en Ingeniera Informtica


WaitForSingleObject(hd->moddlhd->mutexsem, INFINITE); hd->recfun = func; hd->param = param; hd->detectthread = CreateThread(NULL, 0, __moddl_detectproc__, hd, 0, &tid); if (hd->detectthread == INVALID_HANDLE_VALUE) { hd->recfun = NULL; hd->param = NULL; ReleaseSemaphore(hd->moddlhd->mutexsem, 1, NULL); return 0; } ReleaseSemaphore(hd->moddlhd->mutexsem, 1, NULL); return 1; } /* No se pudo definir la funcin manejadora de mensajes recibidos. */ return 0; } /* Funcin modsp_poll: Verifica la llegada de un nuevo mensaje. */ int moddl_poll(moddlconn_hd *hd) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->moddlhd->mutexsem, INFINITE); /* Verifica la recepcin de un mensaje. */ result = modplc_dlpoll(hd->moddlhd->modplchd, hd->handle); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->moddlhd->mutexsem, 1, NULL); /* Devuelve el resultado de la verificacin de la recepcin de un mensaje. */ return result; } /* Funcin moddl_getaddress: Devuelve la direccin fsica de la capa de enlace del modem PLC. */ int moddl_getaddress(moddl_hd *hd, unsigned char iface, moddl_phyaddr addr) { /* Variables. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Obtiene la direccin fsica. */ result = modplc_dlgetaddress(hd->modplchd, iface, addr); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL);

414

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Devuelve el resultado de la bsqueda. */ return result; } /* Funcin moddl_addlogaddress: Agrega una nueva direccin lgica a la capa de enlace del modem PLC. */ int moddl_addlogaddress(moddl_hd *hd, unsigned char iface, unsigned char prot, moddl_logaddr addr) { /* Variables. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Agrega una nueva direccin lgica. */ result = modplc_dladdlogaddress(hd->modplchd, iface, prot, addr); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve el resultado del agregado de la direccin lgica. */ return result; } /* Funcin moddl_dellogaddress: Elimina una direccin lgica a la capa de enlace del modem PLC. */ int moddl_dellogaddress(moddl_hd *hd, unsigned char iface, unsigned char prot, moddl_logaddr addr) { /* Variables. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Elimina una direccin lgica. */ result = modplc_dldellogaddress(hd->modplchd, iface, prot, addr); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve el resultado de la eliminacin de la direccin lgica. */ return result; } /* Funcin moddl_getphyaddress: Devuelve la direccin fsica asociada a la direccin lgica de la capa de enlace del modem PLC. */ int moddl_getphyaddress(moddl_hd *hd, unsigned char iface, unsigned char prot, moddl_logaddr laddr, moddl_phyaddr paddr) { /* Variables. */ int result; /* Resultado de la operacin. */

FernandoArielBeunza79156

415

Tesis de Grado en Ingeniera Informtica


/* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Obtiene la direccin fsica asociada a la direccin lgica. */ result = modplc_dlgetphyaddress(hd->modplchd, iface, prot, laddr, paddr); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve el resultado de la bsqueda. */ return result; } /* Funcin moddl_status: Devuelve el estado del modem PLC. */ int moddl_status(moddl_hd *hd) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Obtiene el estado del modem PLC. */ result = modplc_status(hd->modplchd); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve el resultado del modem PLC. */ return result; } /* Funcin moddl_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de enlace del modem PLC. */ size_t moddl_getpayloadsize(moddl_hd *hd, unsigned char iface) { /* Variables. */ size_t payloadsize; /* Cantidad mxima de bytes que puede contener un mensaje. */

/* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ payloadsize = modplc_dlgetpayloadsize(hd->modplchd, iface); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve la cantidad mxima de bytes que puede contener un mensaje. */

416

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


return payloadsize; }

/* Implementacin de funciones privadas. */ /* Funcin __moddl_detectproc__: Verifica la existencia de un mensaje recibido disponible para ser ledo. */ static DWORD WINAPI __moddl_detectproc__(LPVOID param) { /* Variables. */ int recvflag; size_t msgsize; moddl_phyaddr addr; moddlconn_hd *hd;

/* Indicador de recepcin de un mensaje. */ /* Tamao del mensaje recibido. */ /* Direccin fsica de origen del mensaje. */ /* Manejador de conexin por medio de la capa de enlace del modem PLC. */

void (*func) (void *, moddl_phyaddr, void *, size_t, void *); char *msg;

/* Manejador de mensajes recibidos. */ /* Puntero al mensaje recibido. */

/* Carga el manejador de conexin por medio de la capa de enlace del modem PLC. */ hd = (moddlconn_hd *) param; /* Verifica la existencia de un mensaje recibido. */ while(1) { /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->moddlhd->mutexsem, INFINITE); /* Verifica la recepcin de un mensaje. */ func = hd->recfun; if (!func) break; recvflag = modplc_dlpoll(hd->moddlhd->modplchd, hd->handle); if (recvflag) { msg = (unsigned char *) malloc(hd->payloadsize * sizeof(unsigned char)); if (msg) msgsize = modplc_dlreceive(hd->moddlhd->modplchd, hd->handle, addr, msg, hd->payloadsize); else recvflag = 0; } /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->moddlhd->mutexsem, 1, NULL); /* Verifica si se ha detectado la recepcin de un mensaje para invocar a la funcin manejadora de mensajes recibidos. */ if (recvflag) { func(hd, addr, msg, msgsize, hd->param); free(msg); } } /* Fin de ejecucin del hilo de deteccin de recepcin. */ ReleaseSemaphore(hd->moddlhd->mutexsem, 1, NULL); return 0; }

FernandoArielBeunza79156

417

Tesis de Grado en Ingeniera Informtica

C.3.4.10. Archivo modphy.h


/* modphy.h: Declaracin de funciones referentes a la interfaz de la capa fsica del modem PLC. */

#if !defined(__MODPHY_H__) #define __MODPHY_H__

/* Archivos includos necesarios. */ #include "config.h" #include "modplc.h"

/* Definicin de tipos. */ /* Manejador de interfaz con la capa fsica del modem PLC. */ typedef struct { HANDLE mutexsem; /* Semforo de finalizacin de deteccin de recepcin. */ modplc_hd *modplchd; /* Manejador de interfaz con el modem PLC. */ struct { DWORD threadid; /* Identificador de hilo de deteccin. */ HANDLE detectthread; /* Manejador de hilo de deteccin de recepcin. */ void (*recfun)(void *, void *); /* Funcin manejadora de tramas capturadas. */ void *param; /* Parmetros para la funcin manejadora de tramas recibidas. */ } iface[256]; /* Tabla de interfaces fsicas. */ } modphy_hd;

/* Definicin de constantes. */ /* Tipos de seales. */ #define MODPHY_NOISESIGNAL #define MODPHY_TESTSIGNAL1 #define MODPHY_TESTSIGNAL2

0x01 0x02 0x03

/* Declaracin de funciones pblicas. */ /* Funcin modphy_init: Inicializa los recursos utilizados por la capa fsica del modem PLC. */ modphy_hd *modphy_init(int, int); /* Funcin modphy_release: Libera los recursos utilizados por la capa fsica del modem PLC. */ int modphy_release(modphy_hd *); /* Funcin modphy_sndframe: Enva una trama. */ size_t modphy_sndframe(modphy_hd *, unsigned char, const void *, size_t);

418

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin modphy_capframe: Captura una trama. */ int modphy_capframe(modphy_hd *, unsigned char, size_t); /* Funcin modphy_getframe: Obtiene una trama capturada previamente. */ size_t modphy_getframe(modphy_hd *, unsigned char, void *, size_t); /* Funcin modphy_notify: Define una funcin manejadora de tramas capturadas. */ int modphy_notify(modphy_hd *, unsigned char, void (*func)(modphy_hd *, void *), void *); /* Funcin modphy_poll: Verifica la captura de una trama. */ int modphy_poll(modphy_hd *, unsigned char); /* Funcin modphy_rsdframe: Reenva una trama. */ int modphy_rsdframe(modphy_hd *, unsigned char); /* Funcin modphy_clrbuffer: Limpia el buffer de captura de tramas. */ int modphy_clrbuffer(modphy_hd *, unsigned char); /* Funcin modphy_sensechannel: Sensa el estado del canal de comunicacin. */ int modphy_sensechannel(modphy_hd *, unsigned char, unsigned char, long int); /* Funcin modphy_gensignal: Genera la seal especificada por medio de la capa fsica del modem PLC. */ int modphy_gensignal(modphy_hd *, unsigned char, int); /* Funcin modphy_tstreceive: Realiza una prueba de recepcin. */ int modphy_tstreceive(modphy_hd *, unsigned char); /* Funcin modphy_status: Devuelve el estado del modem PLC. */ int modphy_status(modphy_hd *); /* Funcin modphy_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener una trama de la capa fsica del modem PLC. */ size_t modphy_getpayloadsize(modphy_hd *, unsigned char);

#endif

FernandoArielBeunza79156

419

Tesis de Grado en Ingeniera Informtica

C.3.4.11. Archivo modphy.c


/* modphy.c: Implementacin de funciones referentes a la interfaz de la capa fsica del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <windows.h> #include <process.h> #include "modplc.h" #include "modphy.h"

/* Declaracin de funciones privadas. */ static DWORD WINAPI __modphy_detectproc__(LPVOID);

/* Implementacin de funciones pblicas. */ /* Funcin modphy_init: Inicializa los recursos utilizados por la capa fsica del modem PLC. */ modphy_hd *modphy_init(int sid, int debugmode) { /* Variables. */ short int iface; modphy_hd *handle;

/* Identificadores de interfaces fsicas. */ /* Manejador de interfaz con la capa fsica del modem PLC. */

/* Crea un nuevo manejador de interfaz con la capa fsica del modem PLC. */ handle = (modphy_hd *) malloc(sizeof(modphy_hd)); if (!handle) return NULL; /* Inicializa el manejador de interfaz con la capa fsica del modem PLC. */ while(1) { /* Inicializa el manejador de interfaz con el modem PLC. */ handle->modplchd = modplc_init(sid, MODPLC_PHYSICALLAYER, debugmode); if (!handle->modplchd) break; /* Inicializa el manejador de tramas capturadas de cada una de las interfaces fsicas. */ for(iface = 0; iface < 256; iface ++) { handle->iface[iface].recfun = NULL; handle->iface[iface].param = NULL; } /* Inicializa semforo. */ handle->mutexsem = CreateSemaphore(NULL, 1, 1, NULL); if (handle->mutexsem == INVALID_HANDLE_VALUE) break; /* Devuelve el manejador creado. */ return handle; } /* No se pudo inicializar la interfaz con la capa fsica del modem PLC. */ modplc_release(handle->modplchd); free(handle); return NULL; } /*

420

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Funcin modphy_release: Libera los recursos utilizados por la capa fsica del modem PLC. */ int modphy_release(modphy_hd *hd) { /* Variables. */ short int iface;

/* Identificadores de interfaces fsicas. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Libera el manejador de captura de tramas. */ for(iface = 0; iface < 256; iface ++) modphy_notify(hd, (unsigned char) (iface & 0x00ff), NULL, NULL); /* Libera la interfaz con el modem PLC. */ modplc_release(hd->modplchd); /* Libera los recursos utilizados por la interfaz con la capa fsica del modem PLC. */ CloseHandle(hd->mutexsem); free(hd); /* xito. */ return 1; } /* Funcin modphy_sndframe: Enva una trama. */ size_t modphy_sndframe(modphy_hd *hd, unsigned char iface, const void *frame, size_t framesize) { /* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Enva una trama. */ framesize = modplc_physndframe(hd->modplchd, iface, frame, framesize); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve la cantidad de bytes envados. */ return framesize; } /* Funcin modphy_capframe: Captura una trama. */ int modphy_capframe(modphy_hd *hd, unsigned char iface, size_t framesize) { /* Variables. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE);

FernandoArielBeunza79156

421

Tesis de Grado en Ingeniera Informtica


/* Captura una trama. */ result = modplc_phycapframe(hd->modplchd, iface, framesize); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve el resultado de la solicitud de captura de una trama. */ return result; } /* Funcin modphy_getframe: Obtiene una trama capturada previamente. */ size_t modphy_getframe(modphy_hd *hd, unsigned char iface, void *frame, size_t framesize) { /* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Obtiene una trama capturada previamente. */ framesize = modplc_phygetframe(hd->modplchd, iface, frame, framesize); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve la cantidad de bytes recibidos. */ return framesize; } /* Funcin modphy_notify: Define una funcin manejadora de tramas capturadas. */ int modphy_notify(modphy_hd *hd, unsigned char iface, void (*func)(modphy_hd *, void *), void *param) { /* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Si la funcin manejadora es nula y no hay ninguna funcin manejadora definida previamente no se hace nada. */ if ((!func) && (!hd->iface[iface].recfun)) return 1; /* Si la funcin manejadora no es nula y hay una funcin manejadora previamente definida actualiza la funcin manejadora. */ if ((func) && (hd->iface[iface].recfun)) { WaitForSingleObject(hd->mutexsem, INFINITE); hd->iface[iface].recfun = func; hd->iface[iface].param = param; ReleaseSemaphore(hd->mutexsem, 1, NULL); return 1; } /* Si la funcin manejadora es nula y hay una funcin manejadora definida previamente se elimina esta ltima. */ if ((!func) && (hd->iface[iface].recfun)) { WaitForSingleObject(hd->mutexsem, INFINITE); hd->iface[iface].recfun = NULL; hd->iface[iface].param = param; ReleaseSemaphore(hd->mutexsem, 1, NULL); WaitForSingleObject(hd->iface[iface].detectthread, INFINITE); return 1; }

422

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Si la funcin manejadora no es nula y no hay una funcin manejadora previamente definida se define la nueva funcin manejadora. */ if ((func) && (!hd->iface[iface].recfun)) { WaitForSingleObject(hd->mutexsem, INFINITE); hd->iface[iface].recfun = func; hd->iface[iface].param = param; hd->iface[iface].detectthread = CreateThread(NULL, 0, __modphy_detectproc__, hd, 0, &(hd->iface[iface].threadid)); if (hd->iface[iface].detectthread == INVALID_HANDLE_VALUE) { hd->iface[iface].recfun = NULL; hd->iface[iface].param = NULL; ReleaseSemaphore(hd->mutexsem, 1, NULL); return 0; } ReleaseSemaphore(hd->mutexsem, 1, NULL); return 1; } /* No se pudo definir la funcin manejadora de tramas capturadas. */ return 0; } /* Funcin modphy_poll: Verifica la captura de una trama. */ int modphy_poll(modphy_hd *hd, unsigned char iface) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Verifica la captura de una trama. */ result = modplc_phypoll(hd->modplchd, iface); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve el resultado de la verificacin de la captura de una trama. */ return result; } /* Funcin modphy_rsdframe: Reenva una trama. */ int modphy_rsdframe(modphy_hd *hd, unsigned char iface) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Reenva una trama. */

FernandoArielBeunza79156

423

Tesis de Grado en Ingeniera Informtica


result = modplc_phyrsdframe(hd->modplchd, iface); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve el resultado del reenvo de una trama. */ return result; } /* Funcin modphy_clrbuffer: Limpia el buffer de captura de tramas. */ int modphy_clrbuffer(modphy_hd *hd, unsigned char iface) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Limpia el buffer de captura de tramas. */ result = modplc_phyclrbuffer(hd->modplchd, iface); /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve el resultado de la limpieza del buffer de captura de tramas. */ return result; } /* Funcin modphy_sensechannel: Sensa el estado del canal de comunicacin. */ int modphy_sensechannel(modphy_hd *hd, unsigned char iface, unsigned char level, long int waittime) { /* Variables. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Sensa el estado del canal de comunicacin. */ result = modplc_physensechannel(hd->modplchd, iface, level, waittime); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve el resultado del sensado del canal de comunicacin. */ return result; } /* Funcin modphy_gensignal: Genera la seal especificada por medio de la capa fsica del modem PLC. */ int modphy_gensignal(modphy_hd *hd, unsigned char iface, int sig) { /* Variables. */

424

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Genera la seal especificada. */ result = modplc_phygensignal(hd->modplchd, iface, sig); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve el resultado de la generacin de la seal. */ return result; } /* Funcin modphy_tstreceive: Realiza una prueba de recepcin. */ int modphy_tstreceive(modphy_hd *hd, unsigned char iface) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Realiza una prueba de recepcin. */ result = modplc_phytstreceive(hd->modplchd, iface); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve el resultado de la prueba de recepcin. */ return result; } /* Funcin modphy_status: Devuelve el estado del modem PLC. */ int modphy_status(modphy_hd *hd) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Obtiene el estado del modem PLC. */ result = modplc_status(hd->modplchd); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve el resultado del modem PLC. */

FernandoArielBeunza79156

425

Tesis de Grado en Ingeniera Informtica


return result; } /* Funcin modphy_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener una trama de la capa fsica del modem PLC. */ size_t modphy_getpayloadsize(modphy_hd *hd, unsigned char iface) { /* Variables. */ size_t payloadsize; /* Cantidad mxima de bytes que puede contener una trama. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Obtiene la cantidad mxima de bytes que puede contener una trama. */ payloadsize = modplc_phygetpayloadsize(hd->modplchd, iface); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Devuelve la cantidad mxima de bytes que puede contener una trama. */ return payloadsize; }

/* Implementacin de funciones privadas. */ /* Funcin __modphy_detectproc__: Verifica la existencia de una trama capturada disponible para ser leda. */ static DWORD WINAPI __modphy_detectproc__(LPVOID param) { /* Variables. */ int captureflag; short int i; unsigned char iface; modphy_hd *hd; void (*func)(void *, void *);

/* Indicador de captura de una trama. */ /* Contador. */ /* Identificadores de interfaces fsicas. */ /* Manejador de interfaz con la capa fsica del modem PLC. */ /* Manejador de captura de tramas. */

/* Carga el manejador de interfaz con la capa fsica del modem PLC. */ hd = (modphy_hd *) param; /* Obtiene el identificador de interface fsica asociado al hilo de deteccin de recepcin. */ iface = 0; WaitForSingleObject(hd->mutexsem, INFINITE); for(i = 0; i < 256; i++) { if (hd->iface[i].threadid != GetCurrentThreadId()) continue; iface = (unsigned char) (i & 0x00ff); break; } ReleaseSemaphore(hd->mutexsem, 1, NULL); if (i > 255) return 0; /* Verifica la existencia de una trama capturada. */ while(1)

426

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


{ /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ WaitForSingleObject(hd->mutexsem, INFINITE); /* Verifica la captura de una trama. */ func = hd->iface[iface].recfun; if (!func) break; captureflag = modplc_phypoll(hd->modplchd, iface); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); /* Verifica si se ha detectado la captura de una trama para invocar al manejador de trama capturadas. */ if (captureflag) func(hd, hd->iface[iface].param); } /* Fin de ejecucin del hilo de deteccin de recepcin. */ ReleaseSemaphore(hd->mutexsem, 1, NULL); return 0; }

C.3.4.12. Archivo modrv.h


/* moddrv.h: Declaracin de funciones referentes al driver del modem PLC. */

#if !defined(__MODDRV_H__) #define __MODDRV_H__

/* Archivos includos necesarios. */ #include "config.h" #include "modphy.h" #include "moddl.h" #include "modsp.h"

/* Definicin de tipos. */ /* Estructura del manejador del driver del modem PLC. */ typedef struct { int port; int layer; int debugmode; int stopflag;

/* /* /* /*

unsigned long int clients; modsp_hd *sphd; moddl_hd *dlhd; modphy_hd *phyhd; } moddrv_hd;

/* /* /* /*

Identificador de puerto. */ Capa del modem PLC utilizada. */ Indicador de modo depuracin. */ Indicador de detencin de ejecucin del driver del modem PLC. */ Cantidad de clientes activos. */ Manejador de interfaz con la capa de sesin del modem PLC. */ Manejador de interfaz con la capa de enlace del modem PLC. */ Manejador de interfaz con la capa fsica del modem PLC. */

/* Declaracin de funciones pblicas. */ /* Funcin moddrv_init:

FernandoArielBeunza79156

427

Tesis de Grado en Ingeniera Informtica


Inicializa los recursos utilizados por el driver del modem PLC. */ moddrv_hd *moddrv_init(int, int); /* Funcin moddrv_release: Libera los recursos utilizados por el driver del modem PLC. */ int moddrv_release(moddrv_hd *); /* Funcin moddrv_run: Ejecuta el driver del modem PLC. */ int moddrv_run(moddrv_hd *); /* Funcin moddrv_stop: Detiene la ejecucin del driver del modem PLC. */ int moddrv_stop(moddrv_hd *);

#endif

C.3.4.13. Archivo moddrv.c


/* moddrv.c: Implementacin de funciones referentes al driver del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdio.h> #include "modphy.h" #include "moddl.h" #include "modsp.h" #include "moddrv.h"

/* Definicin de tipos. */ /* Estructura de informacin compartida entre hilos de ejecucin. */ typedef struct { HANDLE hq; /* Manejador mensajes. HANDLE hm; /* Manejador exclusin moddrv_hd *hd; /* Manejador PLC. */ } __moddrv_shareinf__;

de cola de */ de semforo de mutua. */ del driver del modem

/* Declaracin de funciones privadas. */ static DWORD WINAPI __moddrv_clientthread__(LPVOID); static int __moddrv_phyclient__(moddrv_hd *, HANDLE, HANDLE); static int __moddrv_dlclient__(moddrv_hd *, HANDLE, HANDLE); static int __moddrv_spclient__(moddrv_hd *, HANDLE, HANDLE); static int __moddrv_send__(HANDLE, const void *, size_t); static int __moddrv_receive__(HANDLE, void *, size_t);

/* Implementacin de funciones pblicas. */ /*

428

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Funcin moddrv_init: Inicializa los recursos utilizados por el driver del modem PLC. */ moddrv_hd *moddrv_init(int sid, int debugmode) { /* Variables. */ moddrv_hd *handle;

/* Manejador del driver del modem PLC. */

/* Crea un nuevo manejador del driver del modem PLC. */ handle = (moddrv_hd *) malloc(sizeof(moddrv_hd)); if (!handle) return NULL; /* Inicializa el driver del modem PLC. */ handle->port = sid; handle->layer = 0; handle->clients = 0; handle->debugmode = debugmode; handle->stopflag = 0; /* Devuelve el manejador creado. */ return handle; } /* Funcin moddrv_release: Libera los recursos utilizados por el driver del modem PLC. */ int moddrv_release(moddrv_hd *hd) { /* Verifica que el manejador del driver del modem PLC exista. */ if (!hd) return 0; /* Libera los recursos utilizados el driver del modem PLC. */ free(hd); /* xito. */ return 1; } /* Funcin moddrv_run: Ejecuta el driver del modem PLC. */ int moddrv_run(moddrv_hd *hd) { /* Variables. */ DWORD tid; HANDLE hq; HANDLE hm; HANDLE cthread; char qname[256]; __moddrv_shareinf__ sinf;

/* Identificador de hilo. */ /* Manejador de cola de mensajes. */ /* Manejador de semforo de exclusin mutua. */ /* Manejador de hilo. */ /* Nombre de la cola de mensajes. */ /* Informacin compartida. */

/* Verifica que el manejador del driver del modem PLC exista. */ if (!hd) return 0; /* Inicializa semforo. */ hm = CreateSemaphore(NULL, 1, 1, NULL); if (hm == INVALID_HANDLE_VALUE) return 0; /* Procesa las solicitudes de los clientes. */ hd->layer = 0; hd->clients = 0; sprintf(qname, "\\\\.\\pipe\\modemplc%i", hd->port); while(1)

FernandoArielBeunza79156

429

Tesis de Grado en Ingeniera Informtica


{ /* Crea una nueva cola de mensajes. */ hq = CreateNamedPipe(qname, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 0, 0, 0, 0); if (hq == INVALID_HANDLE_VALUE) break; /* Espera la conexin de un nuevo cliente. */ if (hd->stopflag) break; ConnectNamedPipe(hq, NULL); /* Crea un nuevo hilo para atender las solicitudes del nuevo cliente. */ sinf.hd = hd; sinf.hq = hq; sinf.hm = hm; cthread = CreateThread(NULL, 0, __moddrv_clientthread__, &sinf, 0, &tid); if (cthread == INVALID_HANDLE_VALUE) break; } /* Fin de ejecucin del driver del modem PLC. */ CloseHandle(hq); CloseHandle(hm); return 1; } /* Funcin moddrv_stop: Detiene la ejecucin del driver del modem PLC. */ int moddrv_stop(moddrv_hd *hd) { /* Variables. */ HANDLE hq; int layer; int result; char qname[256];

/* Manejador de cola de mensajes. */ /* Capa que se solicita utilizar. */ /* Respuesta a la solicitud. */ /* Nombre de la cola de mensajes. */

/* Verifica que el manejador del driver del modem PLC exista. */ if (!hd) return 0; /* Abre una conexin con la cola de mensajes del driver del modem PLC. */ sprintf(qname, "\\\\.\\pipe\\modemplc%i", hd->port); hq = CreateFile(qname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hq == INVALID_HANDLE_VALUE) return 0; /* Solicita detener la ejecucin del driver del modem PLC. */ layer = 0; result = 0; if (__moddrv_send__(hq, &layer, sizeof(layer))) { if (__moddrv_receive__(hq, &result, sizeof(result))) result = 1; } if (!result) { CloseHandle(hq); return 0; } /* Cierra la conexin con al cola de mensajes del driver del modem PLC. */ CloseHandle(hq); /* Abre una conexin con la cola de mensajes del driver del modem PLC. */ sprintf(qname, "\\\\.\\pipe\\modemplc%i", hd->port);

430

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


hq = CreateFile(qname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hq == INVALID_HANDLE_VALUE) return 1; /* Cierra la conexin con al cola de mensajes del driver del modem PLC. */ CloseHandle(hq); return 1; }

/* Implementacin de funciones privadas. */ /* Funcin __moddrv_clientthread__: Atiene a los clientes del driver del modem PLC. */ static DWORD WINAPI __moddrv_clientthread__(LPVOID param) { /* Variables. */ HANDLE hq; HANDLE hm; int layer; int result; moddrv_hd *hd; __moddrv_shareinf__ *sinf;

/* Manejador de cola de mensajes. */ /* Manejador de semforo de exclusin mutua. */ /* Capa que se solicita utilizar. */ /* Respuesta a la solicitud. */ /* Manejador del driver del modem PLC. */ /* Informacin compartida. */

/* Carga el manejador de cola de mensajes y el manejador del driver del modem PLC. */ sinf = (__moddrv_shareinf__ *) param; hq = sinf->hq; hd = sinf->hd; hm = sinf->hm; /* Espera el permiso para poder acceder a los recursos del driver del modem PLC. */ WaitForSingleObject(hm, INFINITE); /* Recibe la capa a la cual el cliente quiere acceder. */ while(!__moddrv_receive__(hq, &layer, sizeof(layer))); /* Verifica si se solicita detener la ejecucin del driver del modem PLC. */ if (!layer) { result = 1; hd->stopflag = 1; __moddrv_send__(hq, &result, sizeof(result)); ReleaseSemaphore(hm, 1, NULL); CloseHandle(hq); return 0; } /* Verifica si es vlida la solicitud. */ result = 0; if ((layer >= 1) && (layer <= 3)) { if (!hd->layer) hd->layer = layer; if (hd->layer == layer) result = 1; } /* Verifica si es necesario inicializar alguna interfaz. */ if ((result) && (!hd->clients)) { /* Inicializa la interfaz de la capa fsica del modem PLC. */ if (layer == 1) { hd->phyhd = modphy_init(hd->port, hd->debugmode);

FernandoArielBeunza79156

431

Tesis de Grado en Ingeniera Informtica


if (!hd->phyhd) result = 0; } /* Inicializa la interfaz de la capa de enlace del modem PLC. */ else if (layer == 2) { hd->dlhd = moddl_init(hd->port, hd->debugmode); if (!hd->dlhd) result = 0; } /* Inicializa la interfaz de la capa de sesin del modem PLC. */ else if (layer == 3) { hd->sphd = modsp_init(hd->port, hd->debugmode); if (!hd->sphd) result = 0; } } /* Enva el resultado de la solicitud. */ __moddrv_send__(hq, &result, sizeof(result)); if (!result) { if (!hd->clients) hd->layer = 0; ReleaseSemaphore(hm, 1, NULL); CloseHandle(hq); return 0; } /* Agrega un nuevo cliente. */ hd->clients ++; /* Permite a otro hilos el acceso a los recursos del driver del modem PLC. */ ReleaseSemaphore(hm, 1, NULL); /* Verifica si el cliente solicit acceder a la capa fsica. */ if (layer == 1) __moddrv_phyclient__(hd, hq, hm); /* Verifica si el cliente solicit acceder a la capa de enlace. */ else if (layer == 2) __moddrv_dlclient__(hd, hq, hm); /* Verifica si el cliente solicit acceder a la capa de aplicacin. */ else if (layer == 3) __moddrv_spclient__(hd, hq, hm); /* Espera el permiso para poder acceder a los recursos del driver del modem PLC. */ WaitForSingleObject(hm, INFINITE); /* Elimina un cliente. */ hd->clients --; /* Verifica si es necesario liberar alguna interfaz. */ if (!hd->clients) { /* Libera la interfaz de la capa fsica del modem PLC. */ if (layer == 1) modphy_release(hd->phyhd); /* Libera la interfaz de la capa de enlace del modem PLC. */ else if (layer == 2) moddl_release(hd->dlhd); /* Libera la interfaz de la capa de sesin del modem PLC. */ else if (layer == 3) modsp_release(hd->sphd); /* No se esta utilizando ninguna capa. */ hd->layer = 0; } /* Permite a otro hilos el acceso a los recursos del driver del modem PLC. */ ReleaseSemaphore(hm, 1, NULL);

432

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Fin de ejecucin del hilo de deteccin de recepcin. */ CloseHandle(hq); return 0; } /* Funcin __moddrv_phyclient__: Procesa las solicitudes de los clientes destinadas a la capa fsica del modem PLC. */ static int __moddrv_phyclient__(moddrv_hd *hd, HANDLE hq, HANDLE hm) { /* Variables. */ int op; /* Cdigo de operacin. */ int sig; /* Tipo de seal. */ int result; /* Respuesta a la solicitud. */ size_t size; /* Cantidad de bytes. */ unsigned char iface; /* Identificador de interfaz fsica. */ unsigned char level; /* Nivel de seal. */ long int waittime; /* Tiempo de espera. */ unsigned char *frame; /* Puntero a la trama recibida. */

/* Procesa solicitudes destinadas a la capa fsica del modem PLC. */ while(!hd->stopflag) { /* Recibe el cdigo de operacin. */ if (!__moddrv_receive__(hq, &op, sizeof(op))) continue; /* Espera el permiso para poder acceder a los recursos del driver del modem PLC. */ WaitForSingleObject(hm, INFINITE); /* Solicita terminar la conexin. */ if (op == MODDRVPHY_RELEASE) { result = 1; if (!__moddrv_send__(hq, &result, sizeof(result))) continue; break; } /* Solicita el envo de una trama. */ else if (op == MODDRVPHY_SNDFRAME) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Recibe el tramao de la trama. */ if (!__moddrv_receive__(hq, &size, sizeof(size))) continue; /* Recibe la trama. */ frame = (unsigned char *) malloc(size * sizeof(unsigned char)); if (!frame) continue; if (!__moddrv_receive__(hq, frame, size)) { free(frame); continue; } /* Enva la trama. */ size = modphy_sndframe(hd->phyhd, iface, frame, size); free(frame); /* Enva la cantidad de bytes enviados. */ if (!__moddrv_send__(hq, &size, sizeof(size))) continue; } /* Solicita la captura de una trama. */ else if (op == MODDRVPHY_CAPFRAME) { /* Recibe el identificador de interfaz fsica. */

FernandoArielBeunza79156

433

Tesis de Grado en Ingeniera Informtica


if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Recibe el tramao de la trama. */ if (!__moddrv_receive__(hq, &size, sizeof(size))) continue; /* Catura una trama. */ result = modphy_capframe(hd->phyhd, iface, size); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita la lectura de una trama capturada. */ else if (op == MODDRVPHY_GETFRAME) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Recibe el tamao de la trama. */ if (!__moddrv_receive__(hq, &size, sizeof(size))) continue; /* Catura una trama. */ frame = (unsigned char *) malloc(size * sizeof(unsigned char)); if (!frame) continue; size = modphy_getframe(hd->phyhd, iface, frame, size); /* Enva la trama leda. */ if (!__moddrv_send__(hq, frame, size)) { free(frame); continue; } free(frame); /* Enva la cantidad de bytes ledos. */ if (!__moddrv_send__(hq, &size, sizeof(size))) continue; } /* Solicita la verificacin de la captura de una trama. */ else if (op == MODDRVPHY_POLL) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Verifica de la captura de una trama. */ result = modphy_poll(hd->phyhd, iface); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita el reenvo de una trama. */ else if (op == MODDRVPHY_RSDFRAME) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Reenva una trama. */ result = modphy_rsdframe(hd->phyhd, iface); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita la limpieza del buffer de captura de tramas. */ else if (op == MODDRVPHY_CLRBUFFER) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Limpia el buffer de captura de tramas. */ result = modphy_clrbuffer(hd->phyhd, iface); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue;

434

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


} /* Solicita el sensado del canal de comunicacin. */ else if (op == MODDRVPHY_SENSECHANNEL) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Recibe el nivel de seal. */ if (!__moddrv_receive__(hq, &level, sizeof(level))) continue; /* Recibe el tiempo de espera. */ if (!__moddrv_receive__(hq, &waittime, sizeof(waittime))) continue; /* Sensa el estado del canal de comunicacin. */ result = modphy_sensechannel(hd->phyhd, iface, level, waittime); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita la generacin de una seal. */ else if (op == MODDRVPHY_GENSIGNAL) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Recibe el tipo de seal. */ if (!__moddrv_receive__(hq, &sig, sizeof(sig))) continue; /* Genera la seal solicitada. */ result = modphy_gensignal(hd->phyhd, iface, sig); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita realizar una prueba de recepcin. */ else if (op == MODDRVPHY_TSTRECEIVE) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Realiza la prueba de recepcin. */ result = modphy_tstreceive(hd->phyhd, iface); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita verifica el estado del modem PLC. */ else if (op == MODDRVPHY_STATUS) { /* Verifica el estado del modem PLC. */ result = modphy_status(hd->phyhd); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita la cantidad mxima de bytes que puede contener una trama. */ else if (op == MODDRVPHY_GETPAYLOADSIZE) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Obtiene la cantidad mxima de bytes que puede contener una trama. */ size = modphy_getpayloadsize(hd->phyhd, iface); if (!__moddrv_send__(hq, &size, sizeof(size))) continue; } /* Solicitud desconocida. */ else { result = 0;

FernandoArielBeunza79156

435

Tesis de Grado en Ingeniera Informtica


if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Permite a otro hilos el acceso a los recursos del driver del modem PLC. */ ReleaseSemaphore(hm, 1, NULL); } ReleaseSemaphore(hm, 1, NULL); return 0; } /* Funcin __moddrv_dlclient__: Procesa las solicitudes de los clientes destinadas a la capa de enlace del modem PLC. */ static int __moddrv_dlclient__(moddrv_hd *hd, HANDLE hq, HANDLE hm) { /* Variables. */ int op; /* Cdigo de operacin. */ int result; /* Respuesta a la solicitud. */ unsigned char prot; /* Identificador de protocolo. */ unsigned char prio; /* Prioridad del mensaje. */ unsigned char iface; /* Identificador de interfaz fsica. */ size_t size; /* Cantidad de bytes. */ moddlconn_hd *dlconnhd; /* Manejador de conexin por medio de la capa de enlace del modem PLC. */ moddl_logaddr laddr; /* Direccin lgica. */ moddl_phyaddr paddr; /* Direccin fsica. */ unsigned char *msg; /* Puntero al mensaje recibido. */

/* Procesa solicitudes destinadas a la capa de enlace del modem PLC. */ dlconnhd = NULL; while(!hd->stopflag) { /* Recibe el cdigo de operacin. */ if (!__moddrv_receive__(hq, &op, sizeof(op))) continue; /* Espera el permiso para poder acceder a los recursos del driver del modem PLC. */ WaitForSingleObject(hm, INFINITE); /* Solicita cerrar la conexin. */ if (op == MODDRVDL_CLOSE) { result = 0; if (moddl_close(dlconnhd)) result = 1; if (!__moddrv_send__(hq, &result, sizeof(result))) continue; break; } /* Solicita abrir la conexin. */ else if (op == MODDRVDL_OPEN) { /* Abre la conexin si no fue abierta anteriormente. */ result = 0; if (!dlconnhd) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Recibe el identificador de protocolo. */ if (!__moddrv_receive__(hq, &prot, sizeof(prot))) continue; /* Abre la conexin. */ dlconnhd = moddl_open(hd->dlhd, iface, prot); if (dlconnhd) result = 1; }

436

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Devuelve el resultado de la operacin. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita enviar un mensaje. */ else if (op == MODDRVDL_SEND) { /* Enva un mensaje. */ size = 0; if (dlconnhd) { /* Recibe la direccin destinataria. */ if (!__moddrv_receive__(hq, paddr, sizeof(paddr))) continue; /* Recibe la prioridad del mensaje. */ if (!__moddrv_receive__(hq, &prio, sizeof(prio))) continue; /* Recibe el tamao del mensaje. */ if (!__moddrv_receive__(hq, &size, sizeof(size))) continue; /* Recibe el mensaje. */ msg = (unsigned char *) malloc(size * sizeof(unsigned char)); if (!msg) continue; if (!__moddrv_receive__(hq, msg, size)) { free(msg); continue; } /* Enva el mensaje. */ size = moddl_send(dlconnhd, paddr, prio, msg, size); free(msg); } /* Devuelve la cantidad de bytes enviados. */ if (!__moddrv_send__(hq, &size, sizeof(size))) continue; } /* Solicita recibir un mensaje. */ else if (op == MODDRVDL_RECEIVE) { /* Recibe un mensaje. */ size = 0; msg = NULL; if (dlconnhd) { /* Recibe el tamao del mensaje. */ if (!__moddrv_receive__(hq, &size, sizeof(size))) continue; /* Recibe el mensaje. */ msg = (unsigned char *) malloc(size * sizeof(unsigned char)); if (!msg) continue; size = moddl_receive(dlconnhd, paddr, msg, size); } /* Devuelve la cantidad de bytes recibidos. */ if (!__moddrv_send__(hq, &size, sizeof(size))) { if (msg) free(msg); continue; } if (!size) { free(msg); continue; } /* Enva la direccin de origen del mensaje. */ if (!__moddrv_send__(hq, paddr, sizeof(paddr))) { free(msg); continue; }

FernandoArielBeunza79156

437

Tesis de Grado en Ingeniera Informtica


/* Enva la direccin de origen del mensaje. */ if (!__moddrv_send__(hq, msg, size)) { free(msg); continue; } free(msg); } /* Solicita la verificacin de un mensaje. */ else if (op == MODDRVDL_POLL) { /* Verifica de la recepcin de un mensaje. */ result = 0; if (dlconnhd) result = moddl_poll(dlconnhd); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita la direccin fsica del modem PLC. */ else if (op == MODDRVDL_GETADDRESS) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Obtiene la direccin fsica. */ result = moddl_getaddress(hd->dlhd, iface, paddr); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; if (!result) continue; /* Enva la direccin fsica solicitada. */ if (!__moddrv_send__(hq, paddr, sizeof(paddr))) continue; } /* Solicita agregar una nueva direccin lgica. */ else if (op == MODDRVDL_ADDLOGADDRESS) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Recibe el identificador de protocolo. */ if (!__moddrv_receive__(hq, &prot, sizeof(prot))) continue; /* Recibe la direccin lgica. */ if (!__moddrv_receive__(hq, &laddr, sizeof(laddr))) continue; /* Agrega la direccin lgica. */ result = moddl_addlogaddress(hd->dlhd, iface, prot, laddr); /* Devuelve el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita eliminar una direccin lgica. */ else if (op == MODDRVDL_DELLOGADDRESS) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Recibe el identificador de protocolo. */ if (!__moddrv_receive__(hq, &prot, sizeof(prot))) continue; /* Recibe la direccin lgica. */ if (!__moddrv_receive__(hq, &laddr, sizeof(laddr))) continue; /* Elimina la direccin lgica. */ result = moddl_dellogaddress(hd->dlhd, iface, prot, laddr); /* Devuelve el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; }

438

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Solicita obtener la direccin fsica asociada a la direccin lgica. */ else if (op == MODDRVDL_GETPHYADDRESS) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Recibe el identificador de protocolo. */ if (!__moddrv_receive__(hq, &prot, sizeof(prot))) continue; /* Recibe la direccin lgica. */ if (!__moddrv_receive__(hq, &laddr, sizeof(laddr))) continue; /* Obtiene la direccin lgica. */ result = moddl_getphyaddress(hd->dlhd, iface, prot, laddr, paddr); /* Devuelve el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; if (!result) continue; /* Enva la direccin fsica. */ if (!__moddrv_send__(hq, paddr, sizeof(paddr))) continue; } /* Solicita verifica el estado del modem PLC. */ else if (op == MODDRVDL_STATUS) { /* Verifica el estado del modem PLC. */ result = moddl_status(hd->dlhd); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita la cantidad mxima de bytes que puede contener un mensaje. */ else if (op == MODDRVDL_GETPAYLOADSIZE) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ size = moddl_getpayloadsize(hd->dlhd, iface); /* Devuelve la cantidad mxima de bytes que puede contener un mensaje. */ if (!__moddrv_send__(hq, &size, sizeof(size))) continue; } /* Solicitud desconocida. */ else { result = 0; if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Permite a otro hilos el acceso a los recursos del driver del modem PLC. */ ReleaseSemaphore(hm, 1, NULL); } ReleaseSemaphore(hm, 1, NULL); return 0; } /* Funcin __moddrv_spclient__: Procesa las solicitudes de los clientes destinadas a la capa de sesin del modem PLC. */ static int __moddrv_spclient__(moddrv_hd *hd, HANDLE hq, HANDLE hm) { /* Variables. */ int op; /* Cdigo de operacin. */

FernandoArielBeunza79156

439

Tesis de Grado en Ingeniera Informtica


int result; size_t size; modsp_grpid grpid; unsigned char nosec; unsigned char *msg; /* /* /* /* Respuesta a la solicitud. */ Cantidad de bytes. */ Identificador de grupo. */ Indicador de mensaje fuera de secuencia. */ /* Puntero al mensaje recibido. */

/* Procesa solicitudes destinadas a la capa de aplicacin del modem PLC. */ while(!hd->stopflag) { /* Recibe el cdigo de operacin. */ if (!__moddrv_receive__(hq, &op, sizeof(op))) continue; /* Espera el permiso para poder acceder a los recursos del driver del modem PLC. */ WaitForSingleObject(hm, INFINITE); /* Solicita terminar la conexin. */ if (op == MODDRVSP_RELEASE) { result = 1; if (!__moddrv_send__(hq, &result, sizeof(result))) continue; break; } /* Solicita el registro del dispositivo como publicador. */ else if (op == MODDRVSP_PUBLISH) { /* Recibe el identificador de grupo. */ if (!__moddrv_receive__(hq, &grpid, sizeof(grpid))) continue; /* Registra el dispositivo como publicador. */ result = modsp_publish(hd->sphd, grpid); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita el registro del dispositivo como suscriptor. */ else if (op == MODDRVSP_SUBSCRIBE) { /* Recibe el identificador de grupo. */ if (!__moddrv_receive__(hq, &grpid, sizeof(grpid))) continue; /* Registra el dispositivo como suscriptor. */ result = modsp_subscribe(hd->sphd, grpid); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita la desvinculacin del dispositivo a un grupo de difusin. */ else if (op == MODDRVSP_LEAVE) { /* Recibe el identificador de grupo. */ if (!__moddrv_receive__(hq, &grpid, sizeof(grpid))) continue; /* Desvincula el dispositivo de un grupo de difusin. */ result = modsp_leave(hd->sphd, grpid); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita el envo de un mensaje. */ else if (op == MODDRVSP_SEND) { /* Recibe el identificador de grupo. */ if (!__moddrv_receive__(hq, &grpid, sizeof(grpid))) continue; /* Recibe el indicador de mensaje fuera de secuencia. */ if (!__moddrv_receive__(hq, &nosec, sizeof(nosec))) continue;

440

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Recibe el tamao del mensaje. */ if (!__moddrv_receive__(hq, &size, sizeof(size))) continue; /* Enva el mensaje solicitado. */ while(1) { /* Recibe el mensaje. */ msg = (unsigned char *) malloc(size * sizeof(unsigned char)); if (!msg) { size = 0; break; } if (!__moddrv_receive__(hq, msg, size)) { size = 0; break; } /* Enva el mensaje. */ size = modsp_send(hd->sphd, grpid, nosec, msg, size); break; } /* Enva la cantidad de bytes enviados. */ if (!__moddrv_send__(hq, &size, sizeof(size))) continue; } /* Solicita la recepcin de un mensaje. */ else if (op == MODDRVSP_RECEIVE) { /* Recibe la cantidad de bytes que se desea recibir del mensaje. */ if (!__moddrv_receive__(hq, &size, sizeof(size))) continue; /* Recibe el mensaje. */ msg = (unsigned char *) malloc(size * sizeof(unsigned char)); if (msg) size = modsp_receive(hd->sphd, &grpid, msg, size); else size = 0; /* Enva la cantidad de bytes recibidos. */ if (!__moddrv_send__(hq, &size, sizeof(size))) continue; if (!size) continue; /* Enva el indentificador del grupo de difusin por el cual se recibi el mensaje. */ if (!__moddrv_send__(hq, &grpid, sizeof(grpid))) { free(msg); continue; } /* Enva el mensaje recibido. */ if (!__moddrv_send__(hq, msg, size)) { free(msg); continue; } free(msg); } /* Solicita la verificacin de la recepcin de un mensaje. */ else if (op == MODDRVSP_POLL) { /* Verifica de la recepcin de un mensaje. */ result = modsp_poll(hd->sphd); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita verifica el estado del modem PLC. */ else if (op == MODDRVSP_STATUS)

FernandoArielBeunza79156

441

Tesis de Grado en Ingeniera Informtica


{ /* Verifica el estado del modem PLC. */ result = modsp_status(hd->sphd); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita la cantidad mxima de bytes que puede contener un mensaje. */ else if (op == MODDRVSP_GETPAYLOADSIZE) { size = modsp_getpayloadsize(hd->sphd); if (!__moddrv_send__(hq, &size, sizeof(size))) continue; } /* Solicitud desconocida. */ else { result = 0; if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Permite a otro hilos el acceso a los recursos del driver del modem PLC. */ ReleaseSemaphore(hm, 1, NULL); } ReleaseSemaphore(hm, 1, NULL); return 0; } /* Funcin __moddrv_send__: Enva datos por medio de la cola de mensajes. */ static int __moddrv_send__(HANDLE hq, const void *stream, size_t size) { /* Variables. */ size_t sent; /* Cantidad de bytes enviados. */ size_t lastsent; /* Cantidad de bytes enviados en el ltimo envo. */ /* Enva los datos. */ sent = 0; while((stream) && (sent < size)) { if (!WriteFile(hq, stream, size, &lastsent, NULL)) return 0; sent += lastsent; } return 1; } /* Funcin __moddrv_receive__: Enva datos por medio de la cola de mensajes. */ static int __moddrv_receive__(HANDLE hq, void *stream, size_t size) { /* Variables. */ size_t received; /* Cantidad de bytes recibidos. */ size_t lastreceive; /* Cantidad de bytes recibidos en la ltima recepcin. */ /* Enva los datos. */ received = 0; while((stream) && (received < size)) { if (!ReadFile(hq, stream, size, &lastreceive, NULL)) return 0; received += lastreceive; } return 1; }

442

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

C.3.4.14. Archivo modem_driver.c


/* modplc_driver.c: Implementacin de funcin principal del driver del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdio.h> #include "moddrv.h"

/* Funcin main. */ int main(int argc, char *argv[]) { /* Variables. */ int port; int debug; moddrv_hd *hd; char *option;

/* Puerto serie utilizado. */ /* Modo depuracin. */ /* Manejador del driver del modem PLC. */ /* Opcin especificada. */

/* Carga los parmentros */ if (argc < 3) return -1; port = atoi(argv[1]); debug = 0; if (argc > 3) { option = strlwr(strdup(argv[3])); if (!strcmp(option, "debug")) debug = 1; } option = strlwr(strdup(argv[2])); /* Inicializa el driver del modem PLC. */ hd = moddrv_init(port, debug); if (!hd) return 0; /* Evala la opcin solicitada. */ while(1) { /* Activa el driver. */ if (!strcmp(option, "start")) moddrv_run(hd); /* Desactiva el driver. */ else if (!strcmp(option, "stop")) moddrv_stop(hd); break; } /* Libera los recursos del driver del modem PLC. */ moddrv_release(hd); return 0; }

FernandoArielBeunza79156

443

Tesis de Grado en Ingeniera Informtica

C.4. Especificacin del cdigo fuente de las bibliotecas de uso del modem PLC (plataforma Linux)
El cdigo fuente que conforma las bibliotecas de uso del modem PLC, se encuentra organizado en los siguientes componentes:

Interfaz capa de aplicacin. Intefaz capa de enlace. Interfaz capa fsica. Driver del modem PLC.

C.4.1. Interfaz capa de aplicacin modplcap.so


En esta seccin se detalla el cdigo fuente de la biblioteca que implementa la capa de aplicacin del modem PLC, que se compone de los siguientes archivos:

Archivo config.h: en este archivo se definen parmetros de configuracin de la biblioteca dinmica que implementa la capa de aplicacin del modem PLC que no pueden ser modificados en tiempo de ejecucin. Archivo modplcap.h: en este archivo se declaran primitivas con funcionalidades referentes a la capa de aplicacin del modem PLC. Archivo modplcap.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo modplcap.h. Archivo modplcpp.h: en este archivo se declaran las primitivas correspondientes al manejo de la capa de presentacin. Dichas primitivas brindan la capacidad de trabajar con estructuras de datos independientes de la plataforma. Archivo modplcpp.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo modplcpp.h. Archivo modplcsp.h: en este archivo se declaran las primitivas correspondientes al interfaz con la capa de sesin. Dichas primitivas brindan un conjunto de funcionalidades que permiten la comunicacin con la capa de sesin implementada en el modem PLC por medio del driver del mismo. Archivo modplcsp.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo modplcsp.h.

444

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

C.4.1.1. Archivo config.h


/* config.h Definicin de parmetros de configuracin. */

#if !defined(__CONFIG_H__) #define __CONFIG_H__

/* Interfaz con el driver del modem PLC. */ /* Cdigos de operaciones de la interfaz de la capa de sesin. */ #define MODDRVSP_RELEASE 0x00 #define MODDRVSP_PUBLISH 0x01 #define MODDRVSP_SUBSCRIBE 0x02 #define MODDRVSP_LEAVE 0x03 #define MODDRVSP_SEND 0x04 #define MODDRVSP_RECEIVE 0x05 #define MODDRVSP_POLL 0x06 #define MODDRVSP_STATUS 0x07 #define MODDRVSP_GETPAYLOADSIZE 0x08

#endif

C.4.1.2. Archivo modplcsp.h


/* modplcsp.h: Declaracin de funciones referentes a la interfaz de la capa de sesin del modem PLC. */

#if !defined(__MODPLCSP_H__) #define __MODPLCSP_H__

/* Archivos includos necesarios. */ #include "config.h" #include <pthread.h>

/* Definicin de tipos. */ /* Identificador de grupo. */ typedef unsigned char modplcsp_grpid; /* Manejador de interfaz con la capa de sesin del modem PLC. */ typedef struct { int hq; /* Manejador de cola de mensajes. */ pthread_mutex_t hm; /* Semforo de exclusin mtua. */ pthread_t detectthread; /* Manejador de hilo de deteccin de recepcin. */ size_t payloadsize; /* Cantidad mxima de bytes que puede contener un mensaje. */ void (*recfun) (void *, modplcsp_grpid, void *, size_t, void *); /* Funcin manejadora de mensajes recibidos. */ void *param; /* Parmetros para la funcin manejadora de mensajes

FernandoArielBeunza79156

445

Tesis de Grado en Ingeniera Informtica


recibidos. */ } modplcsp_hd;

/* Declaracin de funciones pblicas. */ /* Funcin modplcsp_init: Inicializa los recursos utilizados por la capa de sesin del modem PLC. */ modplcsp_hd *modplcsp_init(int); /* Funcin modplcsp_release: Libera los recursos utilizados por la capa de sesin del modem PLC. */ int modplcsp_release(modplcsp_hd *); /* Funcin modplcsp_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ int modplcsp_publish(modplcsp_hd *, modplcsp_grpid); /* Funcin modplcsp_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ int modplcsp_subscribe(modplcsp_hd *, modplcsp_grpid); /* Funcin modplcsp_leave: Desvincula el dispositivo del grupo de difusin especificado. */ int modplcsp_leave(modplcsp_hd *, modplcsp_grpid); /* Funcin modplcsp_send: Enva un mensaje por medio de la capa de sesin del modem PLC. */ size_t modplcsp_send(modplcsp_hd *, modplcsp_grpid, unsigned char, const void *, size_t); /* Funcin modplcsp_receive: Recibe un mensaje por medio de la capa de sesin del modem PLC. */ size_t modplcsp_receive(modplcsp_hd *, modplcsp_grpid *, void *, size_t); /* Funcin modplcsp_notify: Define una funcin manejadora de mensajes recibidos. */ int modplcsp_notify(modplcsp_hd *, void (*func)(modplcsp_hd *, modplcsp_grpid, void *, size_t, void *), void *); /* Funcin modplcsp_poll: Verifica la llegada de un nuevo mensaje. */ int modplcsp_poll(modplcsp_hd *); /* Funcin modplcsp_status: Devuelve el estado del modem PLC. */ int modplcsp_status(modplcsp_hd *); /*

446

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Funcin modplcsp_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de sesin del modem PLC. */ size_t modplcsp_getpayloadsize(modplcsp_hd *);

#endif

C.4.1.3. Archivo modplcsp.c


/* modplcsp.c: Implementacin de funciones referentes a la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <pthread.h> #include <sys/socket.h> #include <sys/types.h> #include <sys/un.h> #include "modplcsp.h"

/* Declaracin de funciones privadas. */ static void *__modplcsp_detectproc__(void *); static int __modplcsp_sendrecv__(int, void *, size_t, const void *, size_t);

/* Implementacin de funciones pblicas. */ /* Funcin modplcsp_init: Inicializa los recursos utilizados por la capa de sesin del modem PLC. */ modplcsp_hd *modplcsp_init(int sid) { /* Variables. */ int op; int layer; int result; size_t payloadsize; modplcsp_hd *handle; struct sockaddr_un servaddr;

/* Identificador de operacion. */ /* Capa a la que se quiere accerder. */ /* Resultado de la solicitud. */ /* Cantidad mxima de bytes que puede contener un mensaje. */ /* Manejador de interfaz con la capa de sesin del modem PLC. */ /* Direccin del servidor. */

/* Crea un nuevo manejador de interfaz con la capa de sesin del modem PLC. */ handle = (modplcsp_hd *) malloc(sizeof(modplcsp_hd)); if (!handle) return NULL; /* Inicializa el manejador de interfaz con la capa de sesin del modem PLC. */ while(1) { /* Abre una conexin con la cola de mensajes del driver del modem PLC. */ handle->hq = socket(AF_LOCAL, SOCK_STREAM, 0);

FernandoArielBeunza79156

447

Tesis de Grado en Ingeniera Informtica


if (handle->hq < 0) break; bzero(&servaddr, sizeof(servaddr)); servaddr.sun_family = AF_LOCAL; sprintf(servaddr.sun_path, "/tmp/modemplc%i.str", sid); if (connect(handle->hq, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) break; /* Inicializa el manejador de mensajes recibidos. */ handle->param = NULL; handle->recfun = NULL; /* Inicializa semforo de exclusin mtua. */ if (pthread_mutex_init(&(handle->hm), NULL)) break; if (pthread_mutex_unlock(&(handle->hm))) break; /* Solicita acceder a la capa de sesin del modem PLC. */ layer = 3; if (!__modplcsp_sendrecv__(handle->hq, &result, sizeof(result), &layer, sizeof(layer))) break; if (!result) break; /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ op = MODDRVSP_GETPAYLOADSIZE; if (!__modplcsp_sendrecv__(handle->hq, &payloadsize, sizeof(payloadsize), &op, sizeof(op))) break; if (!payloadsize) break; handle->payloadsize = payloadsize; /* Devuelve el manejador creado. */ return handle; } /* No se pudo inicializar la interfaz con la capa sesin del modem PLC. */ pthread_mutex_destroy(&(handle->hm)); close(handle->hq); free(handle); return NULL; } /* Funcin modplcsp_release: Libera los recursos utilizados por la capa de sesin del modem PLC. */ int modplcsp_release(modplcsp_hd *hd) { /* Variables. */ int op; int result;

/* Identificador de operacin. */ /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Libera la funcin manejadora de mensajes recibidos. */ modplcsp_notify(hd, NULL, NULL); /* Solicita la finalizacin del acceso a la capa de sesin del modem PLC. */ op = MODDRVSP_RELEASE; if (!__modplcsp_sendrecv__(hd->hq, &result, sizeof(result), &op, sizeof(op))) return 0; if (!result) return 0; /* Libera los recursos utilizados por el semforo de exclusin mtua. */

448

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


if (pthread_mutex_destroy(&(hd->hm))) return 0; /* Libera los recursos utilizados por la interfaz con la capa de sesin del modem PLC. */ close(hd->hq); free(hd); /* xito. */ return 1; } /* Funcin modplcsp_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ int modplcsp_publish(modplcsp_hd *hd, modplcsp_grpid grpid) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Solicita el registro del dispositivo como publicador. */ result = 0; while(1) { /* Solicita el registro del dispositivo. */ op = MODDRVSP_PUBLISH; if (!__modplcsp_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de grupo. */ __modplcsp_sendrecv__(hd->hq, &result, sizeof(result), &grpid, sizeof(grpid)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve el resultado del registro del dispositivo. */ return result; } /* Funcin modplcsp_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ int modplcsp_subscribe(modplcsp_hd *hd, modplcsp_grpid grpid) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem

FernandoArielBeunza79156

449

Tesis de Grado en Ingeniera Informtica


PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Solicita el registro del dispositivo como suscriptor. */ result = 0; while(1) { /* Solicita el registro del dispositivo. */ op = MODDRVSP_SUBSCRIBE; if (!__modplcsp_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de grupo. */ __modplcsp_sendrecv__(hd->hq, &result, sizeof(result), &grpid, sizeof(grpid)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve el resultado del registro del dispositivo. */ return result; } /* Funcin modplcsp_leave: Desvincula el dispositivo del grupo de difusin especificado. */ int modplcsp_leave(modplcsp_hd *hd, modplcsp_grpid grpid) { /* Variables. */ int op; int result;

/* Identificador de operacin. */ /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Solicita desvincular el dispositivo de un grupo de difusin. */ result = 0; while(1) { /* Solicita desvincular el dispositivo. */ op = MODDRVSP_LEAVE; if (!__modplcsp_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de grupo. */ __modplcsp_sendrecv__(hd->hq, &result, sizeof(result), &grpid, sizeof(grpid)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve el resultado de la desvinculacin del dispositivo. */ return result; } /* Funcin modplcsp_send: Enva un mensaje por medio de la capa de sesin del modem PLC.

450

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


*/ size_t modplcsp_send(modplcsp_hd *hd, modplcsp_grpid grpid, unsigned char nosec, const void *msg, size_t msgsize) { /* Variables. */ int op; /* Identificador de operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Enva un mensaje. */ while(1) { /* Solicita el envo de un mensaje. */ op = MODDRVSP_SEND; if (!__modplcsp_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de grupo. */ if (!__modplcsp_sendrecv__(hd->hq, NULL, 0, &grpid, sizeof(grpid))) break; /* Enva el identificador de mensaje fuera de secuencia. */ if (!__modplcsp_sendrecv__(hd->hq, NULL, 0, &nosec, sizeof(nosec))) break; /* Enva el tamao del mensaje. */ if (!__modplcsp_sendrecv__(hd->hq, NULL, 0, &msgsize, sizeof(msgsize))) break; /* Enva el mensaje. */ if (!__modplcsp_sendrecv__(hd->hq, &msgsize, sizeof(msgsize), msg, msgsize)) break; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) break; /* Devuelve la cantidad de bytes enviados. */ return msgsize; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ pthread_mutex_unlock(&(hd->hm)); /* No se pudo realizar el envo. */ return 0; } /* Funcin modplcsp_receive: Recibe un mensaje por medio de la capa de sesin del modem PLC. */ size_t modplcsp_receive(modplcsp_hd *hd, modplcsp_grpid *grpid, void *msg, size_t msgsize) { /* Variables. */ int op; /* Identificador de operacin. */

FernandoArielBeunza79156

451

Tesis de Grado en Ingeniera Informtica


/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Obtiene un mensaje recibido. */ while(1) { /* Solicita recibir un mensaje. */ op = MODDRVSP_RECEIVE; if (!__modplcsp_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva la cantidad de bytes que se quieren recibir del mensaje. */ if (!__modplcsp_sendrecv__(hd->hq, &msgsize, sizeof(msgsize), &msgsize, sizeof(msgsize))) break; if (!msgsize) break; /* Obtiene el identificador de grupo por el cual se recibi el mensaje. */ if (!__modplcsp_sendrecv__(hd->hq, &grpid, sizeof(grpid), NULL, 0)) break; /* Recibe el mensaje. */ if (!__modplcsp_sendrecv__(hd->hq, msg, msgsize, NULL, 0)) break; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) break; /* Devuelve la cantidad de bytes ledos. */ return msgsize; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ pthread_mutex_unlock(&(hd->hm)); /* No se pudo recibir el mensaje. */ return 0; } /* Funcin modplcsp_notify: Define una funcin manejadora de mensajes recibidos. */ int modplcsp_notify(modplcsp_hd *hd, void (*func)(modplcsp_hd *, modplcsp_grpid, void *, size_t, void *), void *param) { /* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Si la funcin manejadora es nula y no hay ninguna funcin manejadora definida previamente no se hace nada. */ if ((!func) && (!hd->recfun)) return 1; /* Si la funcin manejadora no es nula y hay una funcin manejadora previamente definida actualiza la funcin manejadora. */ if ((func) && (hd->recfun)) { if (pthread_mutex_lock(&(hd->hm))) return 0; hd->recfun = (void (*)(void *, modplcsp_grpid, void *, size_t, void *)) func;

452

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


hd->param = param; if (pthread_mutex_unlock(&(hd->hm))) return 0; return 1; } /* Si la funcin manejadora es nula y hay una funcin manejadora definida previamente se elimina esta ltima. */ if ((!func) && (hd->recfun)) { if (pthread_mutex_lock(&(hd->hm))) return 0; hd->recfun = NULL; hd->param = param; if (pthread_mutex_unlock(&(hd->hm))) return 0; if (pthread_join(hd->detectthread, NULL)) return 0; return 1; } /* Si la funcin manejadora no es nula y no hay una funcin manejadora previamente definida se define la nueva funcin manejadora. */ if ((func) && (!hd->recfun)) { if (pthread_mutex_lock(&(hd->hm))) return 0; hd->recfun = (void (*)(void *, modplcsp_grpid, void *, size_t, void *)) func; hd->param = param; if (pthread_create(&(hd->detectthread), NULL, __modplcsp_detectproc__, hd)) { hd->recfun = NULL; hd->param = NULL; pthread_mutex_unlock(&(hd->hm)); return 0; } if (pthread_mutex_unlock(&(hd->hm))) return 0; return 1; } /* No se pudo definir la funcin manejadora de mensajes recibidos. */ return 0; } /* Funcin modplcsp_poll: Verifica la llegada de un nuevo mensaje. */ int modplcsp_poll(modplcsp_hd *hd) { /* Variables. */ int op; int result;

/* Identificador de operacin. */ /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Solicita verificar la recepcin de un mensaje. */ op = MODDRVSP_POLL; if (!__modplcsp_sendrecv__(hd->hq, &result, sizeof(result), &op, sizeof(op))) result = 0; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0;

FernandoArielBeunza79156

453

Tesis de Grado en Ingeniera Informtica


/* Devuelve el resultado de la solicitud. */ return result; } /* Funcin modplcsp_status: Devuelve el estado del modem PLC. */ int modplcsp_status(modplcsp_hd *hd) { /* Variables. */ int op; int result;

/* Identificador de operacin. */ /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Obtiene el estado del modem PLC. */ op = MODDRVSP_STATUS; if (!__modplcsp_sendrecv__(hd->hq, &result, sizeof(result), &op, sizeof(op))) result = 0; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve el estado del modem PLC. */ return result; } /* Funcin modplcsp_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de sesin del modem PLC. */ size_t modplcsp_getpayloadsize(modplcsp_hd *hd) { /* Variables. */ int op; size_t payloadsize;

/* Identificador de operacin. */ /* Cantidad de bytes que puede contener un mensaje. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ op = MODDRVSP_GETPAYLOADSIZE; if (!__modplcsp_sendrecv__(hd->hq, &payloadsize, sizeof(payloadsize), &op, sizeof(op))) payloadsize = 0; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve la cantidad mxima de bytes que puede contener un mensaje. */ return payloadsize;

454

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


} /* Implementacin de funciones privadas. */ /* Funcin __modplcsp_detectproc__: Verifica la existencia de un mensaje recibido disponible para ser ledo. */ static void *__modplcsp_detectproc__(void *param) { /* Variables. */ int op; int result; int captureflag; size_t msgsize; modplcsp_grpid grpid; modplcsp_hd *hd; void (*func)(void *, modplcsp_grpid, void *, size_t, void *); unsigned char *msg;

/* Identificador de operacin. */ /* Resultado de la operacin. */ /* Indicador de recepcin de un mensaje. */ /* Tamao del mensaje. */ /* Identificador de grupo. */ /* Manejador de interfaz con la capa de sesin del modem PLC. */

/* Funcin manejadora de mensajes recibidos. */ /* Puntero al mensaje. */

/* Carga el manejador de interfaz con la capa de sesin del modem PLC. */ hd = (modplcsp_hd *) param; /* Verifica la existencia de un mensaje recibido. */ while(1) { /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) continue; /* Verifica la recepcin de un mensaje. */ func = hd->recfun; if (!func) break; op = MODDRVSP_POLL; if (__modplcsp_sendrecv__(hd->hq, &result, sizeof(result), &op, sizeof(op))) captureflag = result; /* Recibe el mensaje. */ while(captureflag) { /* Solicita la recepcin de un mensaje. */ op = MODDRVSP_RECEIVE; if (!__modplcsp_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva la cantidad de bytes que se solicita recibir del mensaje. */ msgsize = hd->payloadsize; if (!__modplcsp_sendrecv__(hd->hq, &msgsize, sizeof(msgsize), &msgsize, sizeof(msgsize))) break; if (!msgsize) break; /* Recibe la direccin de origen del mensaje. */ if (!__modplcsp_sendrecv__(hd->hq, &grpid, sizeof(grpid), NULL, 0)) break; /* Recibe el mensaje. */ msg = (unsigned char *) malloc(msgsize * sizeof(unsigned char));

FernandoArielBeunza79156

455

Tesis de Grado en Ingeniera Informtica


if (!msg) { captureflag = 0; break; } __modplcsp_sendrecv__(hd->hq, msg, msgsize, NULL, 0); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ pthread_mutex_unlock(&(hd->hm)); /* Verifica si se ha detectado la recepcin de un mensaje para invocar a la funcin manejadora de mensajes recibidos. */ if (captureflag) { func(hd, grpid, msg, msgsize, hd->param); free(msg); captureflag = 0; } } /* Fin de ejecucin del hilo de deteccin de recepcin. */ pthread_mutex_unlock(&(hd->hm)); return 0; } /* Funcin __modplcsp_sendrecv__: Intercambia datos con el driver del modem PLC. */ static int __modplcsp_sendrecv__(int hq, void *outdata, size_t outsize, const void *indata, size_t insize) { /* Variables. */ size_t last; /* Cantidad de bytes enviados o recibidos. */ size_t sent; /* Cantidad de bytes enviados. */ size_t received; /* Cantidad de bytes recibidos. */

/* Enva la operacin. */ sent = 0; while((indata) && (sent < insize)) { last = write(hq, indata + sent, insize - sent); sent += last; } /* Recibe la respuesta. */ received = 0; while((outdata) && (received < outsize)) { last = read(hq, outdata + received, outsize - received); received += last; } /* xito. */ return 1; }

C.4.1.4. Archivo modplcpp.h


/* modplcpp.h: Declaracin de funciones referentes a la capa de presentacin del modem PLC.

456

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


*/

#if !defined(__MODPLCPP_H__) #define __MODPLCPP_H__

/* Archivos includos necesarios. */ #include "config.h" #include "modplcsp.h"

/* Definicin de tipos. */ /* Identificador de grupo. */ typedef unsigned char modplcpp_grpid; /* Tipo de mensaje. */ typedef unsigned char modplcpp_mtype; /* Tipo de campo. */ typedef unsigned char modplcpp_ftype; /* Estructura del mensaje. */ typedef struct { unsigned short int startoffset; unsigned short int endoffset; modplcpp_grpid grpid; modplcpp_mtype mtype; void *pphd; unsigned char *dat; } modplcpp_msg; /* Manejador de capa de presentacin. */ typedef struct { size_t payloadsize; modplcpp_grpid grpid;

/* /* /* /* /*

Comienzo del mensaje. */ Fin del mensaje. */ Identificador de grupo. */ Tipo de mensaje. */ Manejador de capa de presentacin. */ /* Puntero al contenido del mensaje. */

modplcsp_hd *modsphd; void (*recfun) (void *, modplcpp_msg *, void *); void *param;

/* Cantidad mxima de bytes que puede contener un mensaje. */ /* Identificador de grupo del mensaje almacenado en el buffer. */ /* Manejador de interfaz con la capa de sesin del modem PLC. */

modplcpp_msg buffer; } modplcpp_hd;

/* Funcin manejadora de mensajes recibidos. */ /* Parmetros para la funcin manejadora de mensajes recibidos. */ /* Puntero al buffer de campos recibidos. */

/* Definicin de constantes. */ /* Tipo de mensaje. */ #define MODPLCPP_SECMSG #define MODPLCPP_NOSECMSG /* Tipos de datos. */ #define MODPLCPP_NULLTYPE #define MODPLCPP_CHARTYPE #define MODPLCPP_SINT8TYPE #define MODPLCPP_UINT8TYPE #define MODPLCPP_SINT16TYPE #define MODPLCPP_UINT16TYPE

0x00 0x01

0x00 0x01 0x02 0x03 0x04 0x05

FernandoArielBeunza79156

457

Tesis de Grado en Ingeniera Informtica


#define MODPLCPP_SINT32TYPE #define MODPLCPP_UINT32TYPE #define MODPLCPP_FLOATTYPE 0x06 0x07 0x08

/* Declaracin de funciones pblicas. */ /* Funcin modplcpp_init: Inicializa los recursos utilizado por la capa de presentacin del modem PLC. */ modplcpp_hd *modplcpp_init(int); /* Funcin modplcpp_release: Libera los recursos utilizados por la capa de presentacin del modem PLC. */ int modplcpp_release(modplcpp_hd *); /* Funcin modplcpp_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ int modplcpp_publish(modplcpp_hd *, modplcpp_grpid); /* Funcin modplcpp_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ int modplcpp_subscribe(modplcpp_hd *, modplcpp_grpid); /* Funcin modplcpp_leave: Desvincula el dispositivo del grupo de difusin especificado. */ int modplcpp_leave(modplcpp_hd *, modplcpp_grpid); /* Funcin modplcpp_newmsg: Crea un nuevo mensaje. */ int modplcpp_newmsg(modplcpp_hd *, modplcpp_msg *, modplcpp_grpid, modplcpp_mtype); /* Funcin modplcpp_copymsg: Crea un copia de un mensaje. */ int modplcpp_copymsg(modplcpp_msg *, modplcpp_msg *); /* Funcin modplcpp_putfield: Agrega un nuevo campo al mensaje. */ int modplcpp_putfield(modplcpp_msg *, modplcpp_ftype, unsigned char, const void *); /* Funcin modplcpp_sendmsg: Enva un mensaje por medio de la capa de presentacin. */ int modplcpp_sendmsg(modplcpp_msg *); /* Funcin modplcpp_receivemsg: Recibe un mensaje por medio de la capa de presentacin. */

458

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


int modplcpp_receivemsg(modplcpp_hd *, modplcpp_msg *); /* Funcin modplcpp_getfield: Extrae un campo del mensaje. */ int modplcpp_getfield(modplcpp_msg *, modplcpp_ftype *, unsigned char *, void *); /* Funcin modplcpp_getgrpid: Devuelve el identificador de grupo del mensaje. */ modplcpp_grpid modplcpp_getgrpid(modplcpp_msg *); /* Funcin modplcpp_destroymsg: Destruye un mensaje. */ int modplcpp_destroymsg(modplcpp_msg *); /* Funcin modplcpp_notify: Define una funcin manejadora de mensajes recibidos. */ int modplcpp_notify(modplcpp_hd *, void (*func)(modplcpp_hd *, modplcpp_msg *, void *), void *); /* Funcin modplcpp_poll: Verifica la llegada de un nuevo mensaje. */ int modplcpp_poll(modplcpp_hd *); /* Funcin modplcpp_status: Devuelve el estado del modem PLC. */ int modplcpp_status(modplcpp_hd *);

#endif

C.4.1.5. Archivo modplcpp.c


/* modplcpp.c: Implementacin de funciones referentes a la capa de presentacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdlib.h> #include <string.h> #include "modplcsp.h" #include "modplcpp.h"

/* Declaracin de funciones privadas. */ static void __modplcpp_procmsg__(modplcsp_hd *, modplcsp_grpid, void *, size_t, void *);

/* Implementacin de funciones pblicas. */ /*

FernandoArielBeunza79156

459

Tesis de Grado en Ingeniera Informtica


Funcin modplcpp_init: Inicializa los recursos utilizado por la capa de presentacin del modem PLC. */ modplcpp_hd *modplcpp_init(int sid) { /* Variables. */ modplcpp_hd *handle;

/* Manejador de capa de presentacin. */

/* Crea un nuevo manejador de capa de presentacin. */ handle = (modplcpp_hd *) malloc(sizeof(modplcpp_hd)); if (!handle) return NULL; /* Inicializa el manejador de capa de presentacin. */ while(1) { /* Inicializa el manejador de interfaz con la capa de sesin del modem PLC. */ handle->modsphd = modplcsp_init(sid); if (!handle->modsphd) break; /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ handle->payloadsize = modplcsp_getpayloadsize(handle->modsphd); if (!handle->payloadsize) break; /* Define un manejador de mensajes recibidos por la capa de sesin. */ if (!modplcsp_notify(handle->modsphd, __modplcpp_procmsg__, handle)) break; /* Inicializa el manejador de mensajes recibidos. */ handle->param = NULL; handle->recfun = NULL; /* Devuelve el manejador creado. */ return handle; } /* No se pudo inicializar la interfaz con la capa de presentacin. */ modplcsp_release(handle->modsphd); free(handle); return NULL; } /* Funcin modplcpp_release: Libera los recursos utilizados por la capa de presentacin del modem PLC. */ int modplcpp_release(modplcpp_hd *hd) { /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Libera el manejador de mensajes recibidos. */ modplcsp_notify(hd->modsphd, NULL, NULL); /* Libera la interfaz con la capa de sesin del modem PLC. */ modplcsp_release(hd->modsphd); /* Libera los recursos utilizados por la capa de presentacin. */ free(hd); /* xito. */ return 1; }

460

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin modplcpp_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ int modplcpp_publish(modplcpp_hd *hd, modplcpp_grpid grpid) { /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Registra el dispositivo como publicador del grupo de difusin especificado. */ return modplcsp_publish(hd->modsphd, grpid); } /* Funcin modplcpp_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ int modplcpp_subscribe(modplcpp_hd *hd, modplcpp_grpid grpid) { /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Registra el dispositivo como suscriptor del grupo de difusin especificado. */ return modplcsp_subscribe(hd->modsphd, grpid); } /* Funcin modplcpp_leave: Desvincula el dispositivo del grupo de difusin especificado. */ int modplcpp_leave(modplcpp_hd *hd, modplcpp_grpid grpid) { /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Desvincula el dispositivo del grupo de difusin especificado. */ return modplcsp_leave(hd->modsphd, grpid); } /* Funcin modplcpp_newmsg: Crea un nuevo mensaje. */ int modplcpp_newmsg(modplcpp_hd *hd, modplcpp_msg *msg, modplcpp_grpid grpid, modplcpp_mtype mtype) { /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Asigna memoria para almacenar el contenido del mensaje. */ msg->dat = (unsigned char *) malloc(hd->payloadsize * sizeof(unsigned char)); if (!msg->dat) return 0; /* Inicializa el mensaje. */ msg->startoffset = 0; msg->endoffset = 0; msg->grpid = grpid; msg->mtype = mtype; msg->pphd = hd; return 1; } /*

FernandoArielBeunza79156

461

Tesis de Grado en Ingeniera Informtica


Funcin modplcpp_copymsg: Crea un copia de un mensaje. */ int modplcpp_copymsg(modplcpp_msg *dest, modplcpp_msg *src) { /* Verifica que el puntero al mensaje original no sea nulo. */ if (!src) return 0; /* Verifica que el puntero a la copia del mensaje no sea nulo. */ if (!dest) return 0; /* Asigna memoria para almacenar el contenido del mensaje. */ dest->dat = (unsigned char *) malloc(((modplcpp_hd *) src->pphd)->payloadsize * sizeof(unsigned char)); if (!dest->dat) return 0; /* Inicializa la copia del mensaje. */ dest->startoffset = src->startoffset; dest->endoffset = src->endoffset; dest->grpid = src->grpid; dest->mtype = src->mtype; dest->pphd = src->pphd; memcpy(dest->dat, src->dat, src->endoffset); return 1; } /* Funcin modplcpp_putfield: Agrega un nuevo campo al mensaje. */ int modplcpp_putfield(modplcpp_msg *msg, modplcpp_ftype type, unsigned char count, const void *dat) { /* Variables. */ unsigned char *ptr; /* Puntero a los datos. */ size_t msgsize; /* Tamao del mensaje. */

/* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Inicializa el puntero a los datos. */ ptr = (unsigned char *) dat; /* Verifica si el nuevo campo puede entrar en el mensaje. */ msgsize = msg->endoffset; msgsize += sizeof(modplcpp_ftype); msgsize += sizeof(unsigned char); if ((type == MODPLCPP_CHARTYPE) || (type == MODPLCPP_UINT8TYPE)) msgsize += count * sizeof(unsigned char); else if (type == MODPLCPP_SINT8TYPE) msgsize += count * sizeof(char); else if ((type == MODPLCPP_SINT16TYPE) || (type == MODPLCPP_UINT16TYPE)) msgsize += count * sizeof(unsigned short int); else if ((type == MODPLCPP_SINT32TYPE) || (type == MODPLCPP_UINT32TYPE)) msgsize += count * sizeof(unsigned long int); else if (type == MODPLCPP_FLOATTYPE) msgsize += count * sizeof(float); else return 0; if (msgsize > ((modplcpp_hd *) (msg->pphd))->payloadsize) return 0; /* Agrega el tipo de dato. */ *(msg->dat + msg->endoffset) = type; msg->endoffset += sizeof(modplcpp_ftype); /* Agrega la cantidad de datos. */ *(msg->dat + msg->endoffset) = count;

462

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


msg->endoffset += sizeof(unsigned char); /* Agrega datos tipo caracter o entero de 8 bits sin signo. */ if ((type == MODPLCPP_CHARTYPE) || (type == MODPLCPP_UINT8TYPE)) { while(count--) { *(msg->dat + msg->endoffset) = *ptr; ptr += sizeof(unsigned char); msg->endoffset += sizeof(unsigned char); } } /* Agrega datos tipo entero de 8 bits con signo. */ else if (type == MODPLCPP_SINT8TYPE) { while(count--) { *(msg->dat + msg->endoffset) = *ptr; ptr += sizeof(char); msg->endoffset += sizeof(char); } } /* Agrega datos tipo entero de 16 bits. */ else if ((type == MODPLCPP_SINT16TYPE) || (type == MODPLCPP_UINT16TYPE)) { while(count--) { *(msg->dat + msg->endoffset + 0) = *(ptr + 1); *(msg->dat + msg->endoffset + 1) = *(ptr + 0); ptr += sizeof(unsigned short int); msg->endoffset += sizeof(unsigned short int); } } /* Agrega datos tipo entero de 32 bits. */ else if ((type == MODPLCPP_SINT32TYPE) || (type == MODPLCPP_UINT32TYPE)) { while(count--) { *(msg->dat + msg->endoffset + 0) = *(ptr + 3); *(msg->dat + msg->endoffset + 1) = *(ptr + 2); *(msg->dat + msg->endoffset + 2) = *(ptr + 1); *(msg->dat + msg->endoffset + 3) = *(ptr + 0); ptr += sizeof(unsigned long int); msg->endoffset += sizeof(unsigned long int); } } /* Agrega datos tipo punto flotante. */ else if (type == MODPLCPP_FLOATTYPE) { while(count--) { *(msg->dat + msg->endoffset) = *ptr; ptr += sizeof(float); msg->endoffset += sizeof(float); } } /* xito. */ return 1; } /* Funcin modplcpp_sendmsg: Enva un mensaje por medio de la capa de presentacin. */ int modplcpp_sendmsg(modplcpp_msg *msg) { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0;

FernandoArielBeunza79156

463

Tesis de Grado en Ingeniera Informtica


/* Enva un mensaje. */ if (modplcsp_send(((modplcpp_hd *) (msg->pphd))->modsphd, msg->grpid, msg->mtype, msg->dat, msg->endoffset) == msg->endoffset) return 1; return 0; } /* Funcin modplcpp_receivemsg: Recibe un mensaje por medio de la capa de presentacin. */ int modplcpp_receivemsg(modplcpp_hd *hd, modplcpp_msg *msg) { /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Asigna memoria para almacenar el contenido del mensaje. */ msg->dat = (unsigned char *) malloc(hd->payloadsize * sizeof(unsigned char)); if (!msg->dat) return 0; /* Espera la llegada de un mensaje. */ while(!modplcpp_poll(hd)); /* Devuelve el mensaje almacenado en el buffer de recepcin. */ if (msg) { msg->grpid = hd->buffer.grpid; msg->startoffset = hd->buffer.startoffset; msg->endoffset = hd->buffer.endoffset; msg->pphd = hd; memcpy(msg->dat, hd->buffer.dat, hd->buffer.endoffset); } hd->buffer.endoffset = 0; free(hd->buffer.dat); /* xito. */ return 1; } /* Funcin modplcpp_getfield: Extrae un campo del mensaje. */ int modplcpp_getfield(modplcpp_msg *msg, modplcpp_ftype *type, unsigned char *count, void *dat) { /* Variables. */ unsigned char c; /* Contador. */ unsigned char *ptr; /* Puntero a los datos. */

/* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Inicializa el puntero a los datos. */ ptr = (unsigned char *) dat; /* Extrae el tipo de dato. */ *type = *(msg->dat + msg->startoffset); msg->startoffset += sizeof(modplcpp_ftype); /* Extrae la cantidad de datos. */ c = *(msg->dat + msg->startoffset); *count = c; msg->startoffset += sizeof(unsigned char);

464

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Agrega datos tipo caracter o entero de 8 bits. */ if ((*type == MODPLCPP_CHARTYPE) || (*type == MODPLCPP_SINT8TYPE) || (*type == MODPLCPP_UINT8TYPE)) { while(c --) { *ptr = *(msg->dat + msg->startoffset); ptr += sizeof(unsigned char); msg->startoffset += sizeof(unsigned char); } return 1; } /* Agrega datos tipo entero de 16 bits. */ if ((*type == MODPLCPP_SINT16TYPE) || (*type == MODPLCPP_UINT16TYPE)) { while(c --) { *(ptr + 1) = *(msg->dat + msg->startoffset + 0); *(ptr + 0) = *(msg->dat + msg->startoffset + 1); ptr += sizeof(unsigned short int); msg->startoffset += sizeof(unsigned short int); } return 1; } /* Agrega datos tipo entero de 32 bits. */ if ((*type == MODPLCPP_SINT32TYPE) || (*type == MODPLCPP_UINT32TYPE)) { while(c --) { *(ptr + 3) = *(msg->dat + msg->startoffset + 0); *(ptr + 2) = *(msg->dat + msg->startoffset + 1); *(ptr + 1) = *(msg->dat + msg->startoffset + 2); *(ptr + 0) = *(msg->dat + msg->startoffset + 3); ptr += sizeof(unsigned long int); msg->startoffset += sizeof(unsigned long int); } return 1; } /* Agrega datos tipo punto flotante. */ if (*type == MODPLCPP_FLOATTYPE) { while(c --) { *ptr = *(msg->dat + msg->startoffset); ptr += sizeof(float); msg->startoffset += sizeof(float); } return 1; } /* Tipo de dato desconocido. */ msg->startoffset -= sizeof(unsigned char); msg->startoffset -= sizeof(modplcpp_ftype); return 0; } /* Funcin modplcpp_getgrpid: Devuelve el identificador de grupo del mensaje. */ modplcpp_grpid modplcpp_getgrpid(modplcpp_msg *msg) { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Devuelve el identificador de grupo del mensaje. */ return msg->grpid; }

FernandoArielBeunza79156

465

Tesis de Grado en Ingeniera Informtica


/* Funcin modplcpp_destroymsg: Destruye un mensaje. */ int modplcpp_destroymsg(modplcpp_msg *msg) { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Elimina el contenido del mensaje. */ if (!msg->dat) return 0; free(msg->dat); msg->dat = NULL; return 1; } /* Funcin modplcpp_notify: Define una funcin manejadora de mensajes recibidos. */ int modplcpp_notify(modplcpp_hd *hd, void (*func)(modplcpp_hd *, modplcpp_msg *, void *), void *param) { /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Define un manejador de mensajes recibidos. */ hd->recfun = (void (*)(void *, modplcpp_msg *, void *)) func; hd->param = param; return 1; } /* Funcin modplcpp_poll: Verifica la llegada de un nuevo mensaje. */ int modplcpp_poll(modplcpp_hd *hd) { /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Verifica la llegada de un nuevo mensaje. */ return (hd->buffer.endoffset != 0); } /* Funcin modplcpp_status: Devuelve el estado del modem PLC. */ int modplcpp_status(modplcpp_hd *hd) { /* Verifica que el manejador de la capa de presentacin exista. */ if (!hd) return 0; /* Devuelve el estado del modem PLC. */ return modplcsp_status(hd->modsphd); }

/* Implementacin de funciones privadas. */ /* Funcin __modplcpp_procmsg__: Procesa un mensaje recibido por medio de la capa de sesin. */ static void __modplcpp_procmsg__(modplcsp_hd *hd, modplcsp_grpid grpid, void *msg, size_t msgsize, void *param) { /* Variables. */ modplcpp_hd *pphd; /* Manejador de capa de

466

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


presentacin. */

/* Carga el manejador de capa de presentacin. */ pphd = (modplcpp_hd *) param; /* Verifica si el buffer se encuentra lleno. */ if (pphd->buffer.endoffset != 0) return; /* Reserva memoria para almacenar el mensaje recibido. */ pphd->buffer.dat = (unsigned char *) malloc(msgsize * sizeof(unsigned char)); if (!pphd->buffer.dat) return; /* Acepta el mensaje recibido. */ pphd->buffer.grpid = grpid; pphd->buffer.startoffset = 0; pphd->buffer.endoffset = msgsize; pphd->buffer.pphd = pphd; memcpy(pphd->buffer.dat, msg, msgsize); /* Invoca a la funcin de atencin de recepcin de mensajes registrada. */ if (!pphd->recfun) return; pphd->recfun(pphd, &(pphd->buffer), pphd->param); pphd->buffer.endoffset = 0; free(pphd->buffer.dat); }

C.4.1.6. Archivo modplcap.h


/* modplcap.h: Declaracin de funciones referentes a la interfaz de la capa de aplicacin del modem PLC. */

#if !defined(__MODPLCAP_H__) #define __MODPLCAP_H__

/* Definicin de tipos. */ /* Identificador de grupo. */ typedef unsigned char modplcap_grpid; /* Identificador de mensaje. */ typedef unsigned short int modplcap_msgid; /* Tipo de campo. */ typedef unsigned char modplcap_ftype; /* Estructura del mensaje. */ typedef struct { modplcap_msgid msgid; void *msg; } modplcap_msg; /* Manejador de capa de aplicacin. */ typedef struct { int msgflag; modplcap_grpid grpid;

/* Identificador de mensaje. */ /* Puntero al mensaje. */

void *pphd;

/* Indicador de mensaje en el buffer. */ /* Identificador de grupo del mensaje almacenado en el buffer. */ /* Puntero al manejador de capa de

FernandoArielBeunza79156

467

Tesis de Grado en Ingeniera Informtica


presentacin. */ void (*recfun) (void *, modplcap_msg *, void *); void *param;

modplcap_msg buffer; } modplcap_hd;

/* Funcin manejadora de mensajes recibidos. */ /* Parmetros para la funcin manejadora de mensajes recibidos. */ /* Puntero al buffer de campos recibidos. */

/* Definicin de constantes. */ /* Tipos de datos. */ #define MODPLCAP_NULLTYPE #define MODPLCAP_CHARTYPE #define MODPLCAP_SINT8TYPE #define MODPLCAP_UINT8TYPE #define MODPLCAP_SINT16TYPE #define MODPLCAP_UINT16TYPE #define MODPLCAP_SINT32TYPE #define MODPLCAP_UINT32TYPE #define MODPLCAP_FLOATTYPE

0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08

/* Declaracin de funciones pblicas. */ /* Funcin modplcap_init: Inicializa los recursos utilizados por la capa de aplicacin del modem PLC. */ modplcap_hd *modplcap_init(int); /* Funcin modplcap_release: Libera los recursos utilizados por la capa de aplicacin del modem PLC. */ int modplcap_release(modplcap_hd *); /* Funcin modplcap_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ int modplcap_publish(modplcap_hd *, modplcap_grpid); /* Funcin modplcap_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ int modplcap_subscribe(modplcap_hd *, modplcap_grpid); /* Funcin modplcap_leave: Desvincula el dispositivo del grupo de difusin especificado. */ int modplcap_leave(modplcap_hd *, modplcap_grpid); /* Funcin modplcap_newmsg: Crea un nuevo mensaje. */ int modplcap_newmsg(modplcap_hd *, modplcap_msg *, modplcap_grpid, modplcap_msgid); /* Funcin modplcap_copymsg:

468

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Crea un copia de un mensaje. */ int modplcap_copymsg(modplcap_msg *, modplcap_msg *); /* Funcin modplcap_putfield: Agrega un nuevo campo al mensaje. */ int modplcap_putfield(modplcap_msg *, modplcap_ftype, unsigned char, const void *); /* Funcin modplcap_sendmsg: Enva un mensaje por medio de la capa de aplicacin. */ int modplcap_sendmsg(modplcap_msg *); /* Funcin modplcap_receivemsg: Recibe un mensaje por medio de la capa de aplicacin. */ int modplcap_receivemsg(modplcap_hd *, modplcap_msg *); /* Funcin modplcap_getfield: Extrae un campo del mensaje. */ int modplcap_getfield(modplcap_msg *, modplcap_ftype *, unsigned char *, void *); /* Funcin modplcap_getgrpid: Devuelve el identificador de grupo del mensaje. */ modplcap_grpid modplcap_getgrpid(modplcap_msg *); /* Funcin modplcap_getmsgid: Devuelve el identificador de mensaje. */ modplcap_msgid modplcap_getmsgid(modplcap_msg *); /* Funcin modplcap_destroymsg: Destruye un mensaje. */ int modplcap_destroymsg(modplcap_msg *); /* Funcin modplcap_notify: Define una funcin manejadora de mensajes recibidos. */ int modplcap_notify(modplcap_hd *, void (*func)(modplcap_hd *, modplcap_msg *, void *), void *); /* Funcin modplcap_poll: Verifica la llegada de un nuevo mensaje. */ int modplcap_poll(modplcap_hd *); /* Funcin modplcap_status: Devuelve el estado del modem PLC. */ int modplcap_status(modplcap_hd *);

#endif

FernandoArielBeunza79156

469

Tesis de Grado en Ingeniera Informtica

C.4.1.7. Archivo modplcap.c


/* modplcap.c: Implementacin de funciones referentes a la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "modplcpp.h" #include "modplcap.h"

/* Declaracin de funciones privadas. */ static void __modplcap_procmsg__(modplcpp_hd *, modplcpp_msg *, void *);

/* Implementacin de funciones pblicas. */ /* Funcin modplcap_init: Inicializa los recursos utilizados por la capa de aplicacin del modem PLC. */ modplcap_hd *modplcap_init(int sid) { /* Variables. */ modplcap_hd *handle;

/* Manejador de capa de aplicacin. */

/* Crea un nuevo manejador de capa de aplicacin. */ handle = (modplcap_hd *) malloc(sizeof(modplcap_hd)); if (!handle) return NULL; /* Inicializa el manejador de capa de aplicacin. */ while(1) { /* Inicializa el manejador de capa de presentancin. */ handle->pphd = modplcpp_init(sid); if (!handle->pphd) break; /* Define un manejador de mensajes recibidos por la capa de presentacin. */ if (!modplcpp_notify((modplcpp_hd *) handle->pphd, __modplcap_procmsg__, handle)) break; /* Inicializa el buffer. */ handle->msgflag = 0; /* Inicializa el manejador de mensajes recibidos. */ handle->param = NULL; handle->recfun = NULL; /* Devuelve el manejador creado. */ return handle; } /* No se pudo inicializar la interfaz con la capa de aplicacin. */ modplcpp_release((modplcpp_hd *) handle->pphd); free(handle); return NULL; }

470

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin modplcap_release: Libera los recursos utilizados por la capa de aplicacin del modem PLC. */ int modplcap_release(modplcap_hd *hd) { /* Verifica que el manejador de la capa de aplicacin exista. */ if (!hd) return 0; /* Libera el manejador de mensajes recibidos. */ modplcpp_notify((modplcpp_hd *) hd->pphd, NULL, NULL); /* Libera la interfaz con la capa de presentacin. */ modplcpp_release((modplcpp_hd *) hd->pphd); /* Libera los recursos utilizados por la capa de aplicacin. */ free(hd); /* xito. */ return 1; } /* Funcin modplcap_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ int modplcap_publish(modplcap_hd *hd, modplcap_grpid grpid) { /* Verifica que el manejador de la capa de aplicacin exista. */ if (!hd) return 0; /* Registra el dispositivo como publicador del grupo de difusin especificado. */ return modplcpp_publish((modplcpp_hd *) hd->pphd, grpid); } /* Funcin modplcap_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ int modplcap_subscribe(modplcap_hd *hd, modplcap_grpid grpid) { /* Verifica que el manejador de la capa de aplicacin exista. */ if (!hd) return 0; /* Registra el dispositivo como suscriptor del grupo de difusin especificado. */ return modplcpp_subscribe((modplcpp_hd *) hd->pphd, grpid); } /* Funcin modplcap_leave: Desvincula el dispositivo del grupo de difusin especificado. */ int modplcap_leave(modplcap_hd *hd, modplcap_grpid grpid) { /* Verifica que el manejador de la capa de aplicacin exista. */ if (!hd) return 0; /* Desvincula el dispositivo del grupo de difusin especificado. */ return modplcpp_leave((modplcpp_hd *) hd->pphd, grpid); } /* Funcin modplcap_newmsg: Crea un nuevo mensaje. */ int modplcap_newmsg(modplcap_hd *hd, modplcap_msg *msg, modplcap_grpid grpid, modplcap_msgid msgid)

FernandoArielBeunza79156

471

Tesis de Grado en Ingeniera Informtica


{ /* Verifica que el manejador de la capa de aplicacin exista. */ if (!hd) return 0; /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Inicializa el mensaje. */ msg->msgid = msgid; msg->msg = malloc(sizeof(modplcpp_msg)); if (!msg->msg) return 0; while(1) { if (msgid & 0x8000) { if (!modplcpp_newmsg((modplcpp_hd *) hd->pphd, (modplcpp_msg *) (msg->msg), grpid, MODPLCPP_NOSECMSG)) break; } else { if (!modplcpp_newmsg((modplcpp_hd *) hd->pphd, (modplcpp_msg *) (msg->msg), grpid, MODPLCPP_SECMSG)) break; } if (!modplcpp_putfield((modplcpp_msg *) (msg->msg), MODPLCPP_UINT16TYPE, 1, &msgid)) break; return 1; } free(msg->msg); msg->msg = NULL; return 0; } /* Funcin modplcap_copymsg: Crea un copia de un mensaje. */ int modplcap_copymsg(modplcap_msg *dest, modplcap_msg *src) { /* Verifica que el puntero al mensaje original no sea nulo. */ if (!src) return 0; /* Verifica que el puntero a la copia del mensaje no sea nulo. */ if (!dest) return 0; /* Copia el mensaje. */ dest->msgid = src->msgid; return modplcpp_copymsg((modplcpp_msg *) (dest->msg), (modplcpp_msg *) (src->msg)); } /* Funcin modplcap_putfield: Agrega un nuevo campo al mensaje. */ int modplcap_putfield(modplcap_msg *msg, modplcap_ftype type, unsigned char count, const void *dat) { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Agrega un nuevo campo al mensaje. */ return modplcpp_putfield((modplcpp_msg *) (msg->msg), type, count, dat); } /*

472

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Funcin modplcap_sendmsg: Enva un mensaje por medio de la capa de aplicacin. */ int modplcap_sendmsg(modplcap_msg *msg) { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Enva un mensaje. */ return modplcpp_sendmsg((modplcpp_msg *) (msg->msg)); } /* Funcin modplcap_receivemsg: Recibe un mensaje por medio de la capa de aplicacin. */ int modplcap_receivemsg(modplcap_hd *hd, modplcap_msg *msg) { /* Verifica que el manejador de la capa de aplicacin exista. */ if (!hd) return 0; /* Espera la llegada de un mensaje. */ while(!modplcap_poll(hd)); /* Recibe un mensaje. */ if (msg) { msg->msgid = hd->buffer.msgid; msg->msg = malloc(sizeof(modplcpp_msg)); if (!msg->msg) return 0; memcpy((modplcpp_msg *) (msg->msg), (modplcpp_msg *) (hd->buffer.msg), sizeof(modplcpp_msg)); } modplcpp_destroymsg(hd->buffer.msg); free(hd->buffer.msg); hd->msgflag = 0; return 1; } /* Funcin modplcap_getfield: Extrae un campo del mensaje. */ int modplcap_getfield(modplcap_msg *msg, modplcap_ftype *type, unsigned char *count, void *dat) { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Extrae un campo del mensaje. */ return modplcpp_getfield((modplcpp_msg *) (msg->msg), type, count, dat); } /* Funcin modplcap_getgrpid: Devuelve el identificador de grupo del mensaje. */ modplcap_grpid modplcap_getgrpid(modplcap_msg *msg) { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Devuelve el identificador de grupo del mensaje. */ return ((modplcpp_msg *) (msg->msg))->grpid; } /* Funcin modplcap_getmsgid: Devuelve el identificador de mensaje.

FernandoArielBeunza79156

473

Tesis de Grado en Ingeniera Informtica


*/ modplcap_msgid modplcap_getmsgid(modplcap_msg *msg) { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Devuelve el identificador de grupo del mensaje. */ return msg->msgid; } /* Funcin modplcap_destroymsg: Destruye un mensaje. */ int modplcap_destroymsg(modplcap_msg *msg) { /* Verifica que el puntero al mensaje no sea nulo. */ if (!msg) return 0; /* Destruye el mensaje. */ if (msg->msg) free(msg->msg); msg->msg = NULL; return 1; } /* Funcin modplcap_notify: Define una funcin manejadora de mensajes recibidos. */ int modplcap_notify(modplcap_hd *hd, void (*func)(modplcap_hd *, modplcap_msg *, void *), void *param) { /* Verifica que el manejador de la capa de aplicacin exista. */ if (!hd) return 0; /* Define un manejador de mensajes recibidos. */ hd->recfun = (void (*)(void *, modplcap_msg *, void *)) func; hd->param = param; return 1; } /* Funcin modplcap_poll: Verifica la llegada de un nuevo mensaje. */ int modplcap_poll(modplcap_hd *hd) { /* Verifica que el manejador de la capa de aplicacin exista. */ if (!hd) return 0; /* Verifica la llegada de un nuevo mensaje. */ return (hd->msgflag != 0); } /* Funcin modplcap_status: Devuelve el estado del modem PLC. */ int modplcap_status(modplcap_hd *hd) { /* Verifica que el manejador de la capa de aplicacin exista. */ if (!hd) return 0; /* Devuelve el estado del modem PLC. */ return modplcpp_status(hd->pphd); }

/* Implementacin de funciones privadas. */ /*

474

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Funcin __modplcap_procmsg__: Procesa un mensaje recibido por medio de la capa de presentacin. */ static void __modplcap_procmsg__(modplcpp_hd *hd, modplcpp_msg *msg, void *param) { /* Variables. */ modplcpp_ftype type; /* Tipo de campo. */ modplcap_msgid msgid; /* Identificador de mensaje. */ unsigned char count; /* Contador. */ modplcap_hd *aphd; /* Manejador de capa de aplicacin. */

/* Carga el manejador de capa de aplicacin. */ aphd = (modplcap_hd *) param; /* Verifica si el buffer se encuentra lleno. */ if (aphd->msgflag) return; /* if if if Recibe el mensaje. */ (!modplcpp_getfield(msg, &type, &count, &msgid)) return; (type != MODPLCPP_UINT16TYPE) return; (count != 1) return;

/* Acepta el mensaje recibido. */ aphd->buffer.msgid = msgid; aphd->buffer.msg = malloc(sizeof(modplcpp_msg)); if (!aphd->buffer.msg) return; if (!modplcpp_copymsg((modplcpp_msg *) aphd->buffer.msg, msg)) return; aphd->msgflag = 1; /* Invoca a la funcin de atencin de recepcin de mensajes registrada. */ if (!aphd->recfun) return; aphd->recfun(aphd, &(aphd->buffer), aphd->param); modplcpp_destroymsg(aphd->buffer.msg); free(aphd->buffer.msg); aphd->msgflag = 0; }

C.4.2. Interfaz capa de enlace modplcdl.so


En esta seccin se detalla el cdigo fuente de la biblioteca que implementa la interfaz con la capa de enlace del modem PLC, que se compone de los siguientes archivos:

Archivo config.h: en este archivo se definen parmetros de configuracin de la biblioteca dinmica que implementa la capa de enlace del modem PLC que no pueden ser modificados en tiempo de ejecucin. Archivo modplcdl.h: en este archivo se declaran las primitivas correspondientes al interfaz con la capa de enlace. Dichas primitivas brindan un conjunto de funcionalidades que permiten la comunicacin con la capa de enlace implementada en el modem PLC por medio del driver del mismo. Archivo modplcdl.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo modplcdl.h.

FernandoArielBeunza79156

475

Tesis de Grado en Ingeniera Informtica

C.4.2.1. Archivo config.h


/* config.h Definicin de parmetros de configuracin. */

#if !defined(__CONFIG_H__) #define __CONFIG_H__

/* Interfaz con el driver del modem PLC. */ /* Cdigos de operaciones de la interfaz de la capa de enlace. */ #define MODDRVDL_CLOSE 0x00 #define MODDRVDL_OPEN 0x01 #define MODDRVDL_SEND 0x02 #define MODDRVDL_RECEIVE 0x03 #define MODDRVDL_POLL 0x04 #define MODDRVDL_GETADDRESS 0x05 #define MODDRVDL_ADDLOGADDRESS 0x06 #define MODDRVDL_DELLOGADDRESS 0x07 #define MODDRVDL_GETPHYADDRESS 0x08 #define MODDRVDL_STATUS 0x09 #define MODDRVDL_GETPAYLOADSIZE 0x0a

#endif

C.4.2.2. Archivo modplcdl.h


/* modplcdl.h: Declaracin de funciones referentes a la interfaz de la capa de enlace del modem PLC. */

#if !defined(__MODPLCDL_H__) #define __MODPLCDL_H__

/* Archivos includos necesarios. */ #include <pthread.h>

/* Definicin de tipos. */ /* Direccin fsica del modem PLC. */ typedef unsigned char modplcdl_phyaddr[8]; /* Direccin lgica del modem PLC. */ typedef unsigned long int modplcdl_logaddr; /* Manejador de interfaz con la capa de enlace del modem PLC. */ typedef struct { int hq; /* Manejador de cola de mensajes. */ pthread_mutex_t hm; /* Semforo de exclusin mtua. */ unsigned char sid; /* Identificador de interfaz de comunicacin por puerto serie. */ unsigned long int conncounter; /* Contador de conexiones abiertas. */ } modplcdl_hd;

476

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Manejador de conexin por medio de la capa de enlace del modem PLC. */ typedef struct { int hq; /* Manejador de cola de mensajes. */ pthread_t detectthread; /* Manejador de hilo de deteccin de recepcin. */ size_t payloadsize; /* Cantidad mxima de bytes que puede contener un mensaje. */ modplcdl_hd *dlhd; /* Manejador de interfaz con la capa de enlance del modem PLC. */ void (*recfun) (void *, modplcdl_phyaddr, void *, size_t, void *); /* Funcin manejadora de mensajes recibidos. */ void *param; /* Parmetros para la funcin manejadora de mensajes recibidos. */ } modplcdlconn_hd;

/* Declaracin de funciones pblicas. */ /* Funcin modplcdl_init: Inicializa los recursos utilizados por la capa de enlace del modem PLC. */ modplcdl_hd *modplcdl_init(int); /* Funcin modplcdl_release: Libera los recursos utilizados por la capa de enlace del modem PLC. */ int modplcdl_release(modplcdl_hd *); /* Funcin modplcdl_open: Abre una conexin por medio de la capa de enlace del modem PLC. */ modplcdlconn_hd *modplcdl_open(modplcdl_hd *, unsigned char, unsigned char); /* Funcin modplcdl_close: Cierra una conexin por medio de la capa de enlace del modem PLC. */ int modplcdl_close(modplcdlconn_hd *); /* Funcin modplcdl_send: Enva un mensaje por medio de la capa de enlace del modem PLC. */ size_t modplcdl_send(modplcdlconn_hd *, modplcdl_phyaddr, unsigned char, const void *, size_t); /* Funcin modplcdl_receive: Recibe un mensaje por medio de la capa de enlace del modem PLC. */ size_t modplcdl_receive(modplcdlconn_hd *, modplcdl_phyaddr, void *, size_t); /* Funcin modplcdl_notify: Define una funcin manejadora de mensajes recibidos. */ int modplcdl_notify(modplcdlconn_hd *, void (*func)(modplcdlconn_hd *, modplcdl_phyaddr, void *, size_t, void *), void *); /* Funcin modplcdl_poll:

FernandoArielBeunza79156

477

Tesis de Grado en Ingeniera Informtica


Verifica la recepcin de un mensaje. */ int modplcdl_poll(modplcdlconn_hd *); /* Funcin modplcdl_getaddress: Devuelve la direccin fsica de la capa de enlace del modem PLC. */ int modplcdl_getaddress(modplcdl_hd *, unsigned char, modplcdl_phyaddr); /* Funcin modplcdl_addlogaddress: Agrega una nueva direccin lgica a la capa de enlace del modem PLC. */ int modplcdl_addlogaddress(modplcdl_hd *, unsigned char, unsigned char, modplcdl_logaddr); /* Funcin modplcdl_dellogaddress: Elimina una direccin lgica a la capa de enlace del modem PLC. */ int modplcdl_dellogaddress(modplcdl_hd *, unsigned char, unsigned char, modplcdl_logaddr); /* Funcin modplcdl_getphyaddress: Devuelve la direccin fsica asociada a la direccin lgica de la capa de enlace del modem PLC. */ int modplcdl_getphyaddress(modplcdl_hd *hd, unsigned char, unsigned char, modplcdl_logaddr, modplcdl_phyaddr); /* Funcin modplcdl_status: Devuelve el estado del modem PLC. */ int modplcdl_status(modplcdl_hd *); /* Funcin modplcdl_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de enlace del modem PLC. */ size_t modplcdl_getpayloadsize(modplcdl_hd *, unsigned char);

#endif

C.4.2.3. Archivo modplcdl.c


/* modplcdl.c: Implementacin de funciones referentes a la interfaz de la capa de enlace del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <pthread.h> #include <sys/socket.h> #include <sys/types.h> #include <sys/un.h> #include "modplcdl.h"

478

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

/* Declaracin de funciones privadas. */ static void *__modplcdl_detectproc__(void *); static int __modplcdl_sendrecv__(int, void *, size_t, const void *, size_t);

/* Implementacin de funciones pblicas. */ /* Funcin modplcdl_init: Inicializa los recursos utilizados por la capa de enlace del modem PLC. */ modplcdl_hd *modplcdl_init(int sid) { /* Variables. */ int layer; int result; modplcdl_hd *handle; struct sockaddr_un servaddr;

/* Capa a la que se quiere accerder. */ /* Resultado de la solicitud. */ /* Manejador de interfaz con la capa de enlace del modem PLC. */ /* Direccin del servidor. */

/* Crea un nuevo manejador de interfaz con la capa de enlace del modem PLC. */ handle = (modplcdl_hd *) malloc(sizeof(modplcdl_hd)); if (!handle) return NULL; /* Inicializa el manejador de interfaz con la capa de enlace del modem PLC. */ while(1) { /* Abre una conexin con la cola de mensajes del driver del modem PLC. */ handle->hq = socket(AF_LOCAL, SOCK_STREAM, 0); if (handle->hq < 0) break; bzero(&servaddr, sizeof(servaddr)); servaddr.sun_family = AF_LOCAL; sprintf(servaddr.sun_path, "/tmp/modemplc%i.str", sid); if (connect(handle->hq, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) break; /* Inicializa semforo de exclusin mtua. */ if (pthread_mutex_init(&(handle->hm), NULL)) break; if (pthread_mutex_unlock(&(handle->hm))) break; /* Solicita acceder a la capa de enlace del modem PLC. */ layer = 2; if (!__modplcdl_sendrecv__(handle->hq, &result, sizeof(result), &layer, sizeof(layer))) break; if (!result) break; /* Almacena la interfaz de comunicacin por puerto serie. */ handle->sid = sid; /* Inicializa el contador de conexiones abiertas. */ handle->conncounter = 0; /* Devuelve el manejador creado. */ return handle; } /* No se pudo inicializar la interfaz con la capa de enlace del modem PLC. */ pthread_mutex_destroy(&(handle->hm)); close(handle->hq); free(handle); return NULL;

FernandoArielBeunza79156

479

Tesis de Grado en Ingeniera Informtica


} /* Funcin modplcdl_release: Libera los recursos utilizados por la capa de enlace del modem PLC. */ int modplcdl_release(modplcdl_hd *hd) { /* Variables. */ int op; int result;

/* Identificador de operacin. */ /* Resultado de la solicitud. */

/* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Verifica que no existan conexiones abiertas. */ if (hd->conncounter) return 0; /* Solicita el cierre de la conexin. */ op = MODDRVDL_CLOSE; if (!__modplcdl_sendrecv__(hd->hq, &result, sizeof(result), &op, sizeof(op))) return 0; if (!result) return 0; /* Libera los recursos utilizados por el semforo de exclusin mtua. */ if (pthread_mutex_destroy(&(hd->hm))) return 0; /* Libera los recursos utilizados por la interfaz con la capa de enlace del modem PLC. */ close(hd->hq); free(hd); /* xito. */ return 1; } /* Funcin modplcdl_open: Abre una conexin por medio de la capa de enlace del modem PLC. */ modplcdlconn_hd *modplcdl_open(modplcdl_hd *hd, unsigned char iface, unsigned char prot) { /* Variables. */ int op; /* Identificador de operacin. */ int layer; /* Capa a la que se quiere accerder. */ int result; /* Resultado de la solicitud. */ size_t payloadsize; /* Cantidad de bytes que puede contener un mensaje. */ modplcdlconn_hd *handle; /* Manejador de conexin de la capa de enlace del modem PLC. */ struct sockaddr_un servaddr; /* Direccin del servidor. */

/* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return NULL; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Crea un nuevo manejador de conexin por medio de la capa de enlace del modem PLC. */ handle = (modplcdlconn_hd *) malloc(sizeof(modplcdlconn_hd)); if (!handle) {

480

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


pthread_mutex_unlock(&(hd->hm)); return NULL; } /* Inicializa el manejador de conexin. */ while(1) { /* Carga el manejador de interfaz con la capa de enlace del modem PLC. */ handle->dlhd = hd; /* Abre una conexin con la cola de mensajes del driver del modem PLC. */ handle->hq = socket(AF_LOCAL, SOCK_STREAM, 0); if (handle->hq < 0) break; bzero(&servaddr, sizeof(servaddr)); servaddr.sun_family = AF_LOCAL; sprintf(servaddr.sun_path, "/tmp/modemplc%i.str", hd->sid); if (connect(handle->hq, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) break; /* Solicita acceder a la capa de enlace del modem PLC. */ layer = 2; if (!__modplcdl_sendrecv__(handle->hq, &result, sizeof(result), &layer, sizeof(layer))) break; if (!result) break; /* Solicita abrir una conexin. */ op = MODDRVDL_OPEN; if (!__modplcdl_sendrecv__(handle->hq, NULL, 0, &op, sizeof(op))) break; if (!__modplcdl_sendrecv__(handle->hq, NULL, 0, &iface, sizeof(iface))) break; if (!__modplcdl_sendrecv__(handle->hq, &result, sizeof(result), &prot, sizeof(prot))) break; if (!result) break; /* Solicita la cantidad mxima de bytes que puede contener un mensaje. */ op = MODDRVDL_GETPAYLOADSIZE; if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ if (!__modplcdl_sendrecv__(hd->hq, &payloadsize, sizeof(payloadsize), &iface, sizeof(iface))) break; if (!payloadsize) break; handle->payloadsize = payloadsize; /* Inicializa el manejador de mensajes recibidos. */ handle->param = NULL; handle->recfun = NULL; /* Actualiza el nmero de conexiones. */ handle->dlhd->conncounter ++; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) break; /* Devuelve el manejador creado. */ return handle; }

FernandoArielBeunza79156

481

Tesis de Grado en Ingeniera Informtica


/* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ pthread_mutex_unlock(&(hd->hm)); /* No se pudo abrir la conexin. */ close(handle->hq); free(handle); return NULL; } /* Funcin modplcdl_close: Cierra una conexin por medio de la capa de enlace del modem PLC. */ int modplcdl_close(modplcdlconn_hd *hd) { /* Variables. */ int op; int result;

/* Identificador de operacin. */ /* Resultado de la solicitud. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Libera el manejador de mensajes recibidos. */ modplcdl_notify(hd, NULL, NULL); /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->dlhd->hm))) return 0; /* Solicita el cierre de la conexin. */ op = MODDRVDL_CLOSE; if (!__modplcdl_sendrecv__(hd->hq, &result, sizeof(result), &op, sizeof(op))) return 0; if (!result) return 0; /* Actualiza el nmero de conexiones. */ hd->dlhd->conncounter --; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->dlhd->hm))) return 0; /* Libera los recursos utilizados por la conexin por medio de la capa de enlace del modem PLC. */ close(hd->hq); free(hd); /* xito. */ return 1; } /* Funcin modplcdl_send: Enva un mensaje por medio de la capa de enlace del modem PLC. */ size_t modplcdl_send(modplcdlconn_hd *hd, modplcdl_phyaddr addr, unsigned char prio, const void *msg, size_t msgsize) { /* Variables. */ int op; /* Identificador de operacin. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem

482

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


PLC. */ if (pthread_mutex_lock(&(hd->dlhd->hm))) return 0; /* Enva un mensaje. */ while(1) { /* Solicita el envo de un mensaje. */ op = MODDRVDL_SEND; if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva la direccin destinataria. */ if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, addr, sizeof(modplcdl_phyaddr))) break; /* Enva la prioridad del mensaje. */ if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &prio, sizeof(prio))) break; /* Enva el tamao del mensaje. */ if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &msgsize, sizeof(msgsize))) break; /* Enva el mensaje. */ if (!__modplcdl_sendrecv__(hd->hq, &msgsize, sizeof(msgsize), msg, msgsize)) break; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->dlhd->hm))) break; /* Devuelve la cantidad de bytes enviados. */ return msgsize; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ pthread_mutex_unlock(&(hd->dlhd->hm)); /* No se pudo realizar el envo. */ return 0; } /* Funcin modplcdl_receive: Recibe un mensaje por medio de la capa de enlace del modem PLC. */ size_t modplcdl_receive(modplcdlconn_hd *hd, modplcdl_phyaddr addr, void *msg, size_t msgsize) { /* Variables. */ int op; /* Identificador de operacin. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->dlhd->hm))) return 0; /* Recibe un mensaje. */ while(1) { /* Solicita la recepcin de un mensaje. */ op = MODDRVDL_RECEIVE;

FernandoArielBeunza79156

483

Tesis de Grado en Ingeniera Informtica


if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva la cantidad de bytes que se solicita recibir del mensaje. */ if (!__modplcdl_sendrecv__(hd->hq, &msgsize, sizeof(msgsize), &msgsize, sizeof(msgsize))) break; if (!msgsize) break; /* Recibe la direccin de origen del mensaje. */ if (!__modplcdl_sendrecv__(hd->hq, addr, sizeof(modplcdl_phyaddr), NULL, 0)) break; /* Recibe el mensaje. */ if (!__modplcdl_sendrecv__(hd->hq, msg, msgsize, NULL, 0)) break; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->dlhd->hm))) break; /* Devuelve la cantidad de bytes enviados. */ return msgsize; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ pthread_mutex_unlock(&(hd->dlhd->hm)); /* No se pudo realizar la recepcin. */ return 0; } /* Funcin modplcdl_notify: Define una funcin manejadora de mensajes recibidos. */ int modplcdl_notify(modplcdlconn_hd *hd, void (*func)(modplcdlconn_hd *, modplcdl_phyaddr, void *, size_t, void *), void *param) { /* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Si la funcin manejadora es nula y no hay ninguna funcin manejadora definida previamente no se hace nada. */ if ((!func) && (!hd->recfun)) return 1; /* Si la funcin manejadora no es nula y hay una funcin manejadora previamente definida actualiza la funcin manejadora. */ if ((func) && (hd->recfun)) { if (pthread_mutex_lock(&(hd->dlhd->hm))) return 0; hd->recfun = (void (*)(void *, modplcdl_phyaddr, void *, size_t, void *)) func; hd->param = param; if (pthread_mutex_unlock(&(hd->dlhd->hm))) return 0; return 1; } /* Si la funcin manejadora es nula y hay una funcin manejadora definida previamente se elimina esta ltima. */ if ((!func) && (hd->recfun)) { if (pthread_mutex_lock(&(hd->dlhd->hm))) return 0; hd->recfun = NULL; hd->param = param; if (pthread_mutex_unlock(&(hd->dlhd->hm))) return 0; if (pthread_join(hd->detectthread, NULL)) return 0;

484

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


return 1; } /* Si la funcin manejadora no es nula y no hay una funcin manejadora previamente definida se define la nueva funcin manejadora. */ if ((func) && (!hd->recfun)) { if (pthread_mutex_lock(&(hd->dlhd->hm))) return 0; hd->recfun = (void (*)(void *, modplcdl_phyaddr, void *, size_t, void *)) func; hd->param = param; if (pthread_create(&(hd->detectthread), NULL, __modplcdl_detectproc__, hd)) { hd->recfun = NULL; hd->param = NULL; pthread_mutex_unlock(&(hd->dlhd->hm)); return 0; } if (pthread_mutex_unlock(&(hd->dlhd->hm))) return 0; return 1; } /* No se pudo definir la funcin manejadora de mensajes recibidos. */ return 0; } /* Funcin modplcdl_poll: Verifica la recepcin de un mensaje. */ int modplcdl_poll(modplcdlconn_hd *hd) { /* Variables. */ int op; int result;

/* Identificador de operacin. */ /* Resultado de la operacin. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->dlhd->hm))) return 0; /* Solicita verificar la recepcin de un mensaje. */ op = MODDRVDL_POLL; if (!__modplcdl_sendrecv__(hd->hq, &result, sizeof(result), &op, sizeof(op))) result = 0; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->dlhd->hm))) return 0; /* Devuelve el resultado de la solicitud. */ return result; } /* Funcin modplcdl_getaddress: Devuelve la direccin fsica de la capa de enlace del modem PLC. */ int modplcdl_getaddress(modplcdl_hd *hd, unsigned char iface, modplcdl_phyaddr addr) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

FernandoArielBeunza79156

485

Tesis de Grado en Ingeniera Informtica


/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Obtiene la direccin fsica del modem PLC. */ result = 0; while(1) { /* Solicita la direccin fsica del modem PLC. */ op = MODDRVDL_GETADDRESS; if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva el identifcador de interfaz fsica. */ if (!__modplcdl_sendrecv__(hd->hq, &result, sizeof(result), &iface, sizeof(iface))) break; if (!result) break; /* Recibe la direccin fsica. */ if (!__modplcdl_sendrecv__(hd->hq, addr, sizeof(modplcdl_phyaddr), NULL, 0)) result = 0; break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve el resultado de la solicitud. */ return result; } /* Funcin modplcdl_addlogaddress: Agrega una nueva direccin lgica a la capa de enlace del modem PLC. */ int modplcdl_addlogaddress(modplcdl_hd *hd, unsigned char iface, unsigned char prot, modplcdl_logaddr addr) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Agrega una direccin lgica. */ result = 0; while(1) { /* Solicita agregar una direccin lgica. */ op = MODDRVDL_ADDLOGADDRESS; if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &iface, sizeof(iface)))

486

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


break; /* Enva el identificador de protocolo. */ if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &prot, sizeof(prot))) break; /* Enva la direccin lgica. */ __modplcdl_sendrecv__(hd->hq, &result, sizeof(result), &addr, sizeof(addr)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve el resultado de la solicitud. */ return result; } /* Funcin modplcdl_dellogaddress: Elimina una direccin lgica a la capa de enlace del modem PLC. */ int modplcdl_dellogaddress(modplcdl_hd *hd, unsigned char iface, unsigned char prot, modplcdl_logaddr addr) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Elimina una direccin lgica. */ result = 0; while(1) { /* Solicita la eliminacin de una direccin lgica. */ op = MODDRVDL_DELLOGADDRESS; if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &iface, sizeof(iface))) break; /* Enva el identificador de protocolo. */ if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &prot, sizeof(prot))) break; /* Enva la direccin lgica. */ __modplcdl_sendrecv__(hd->hq, &result, sizeof(result), &addr, sizeof(addr)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve el resultado de la solicitud. */

FernandoArielBeunza79156

487

Tesis de Grado en Ingeniera Informtica


return result; } /* Funcin modplcdl_getphyaddress: Devuelve la direccin fsica asociada a la direccin lgica de la capa de enlace del modem PLC. */ int modplcdl_getphyaddress(modplcdl_hd *hd, unsigned char iface, unsigned char prot, modplcdl_logaddr laddr, modplcdl_phyaddr paddr) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Obtiene la direccin fsica asociada a la direccin lgica. */ result = 0; while(1) { /* Solicita la direccin fsica. */ op = MODDRVDL_GETPHYADDRESS; if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &iface, sizeof(iface))) break; /* Enva el identificador de protocolo. */ if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &prot, sizeof(prot))) break; /* Enva la direccin lgica. */ if (!__modplcdl_sendrecv__(hd->hq, &result, sizeof(result), &laddr, sizeof(laddr))) break; if (!result) break; /* Recibe la direccin fsica. */ __modplcdl_sendrecv__(hd->hq, paddr, sizeof(modplcdl_phyaddr), NULL, 0); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve el resultado de la solicitud. */ return result; } /* Funcin modplcdl_status: Devuelve el estado del modem PLC. */ int modplcdl_status(modplcdl_hd *hd) { /* Variables. */

488

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


int op; int result; /* Identificador de operacin. */ /* Resultado de la operacin. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Obtiene el estado del modem PLC. */ op = MODDRVDL_STATUS; if (!__modplcdl_sendrecv__(hd->hq, &result, sizeof(result), &op, sizeof(op))) result = 0; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve el estado del modem PLC. */ return result; } /* Funcin modplcdl_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de enlace del modem PLC. */ size_t modplcdl_getpayloadsize(modplcdl_hd *hd, unsigned char iface) { /* Variables. */ int op; /* Operacin. */ size_t payloadsize; /* Cantidad de bytes que puede contener un mensaje. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ payloadsize = 0; while(1) { /* Solicita la cantidad mxima de bytes que puede contener un mensaje. */ op = MODDRVDL_GETPAYLOADSIZE; if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ __modplcdl_sendrecv__(hd->hq, &payloadsize, sizeof(payloadsize), &iface, sizeof(iface)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve la cantidad mxima de bytes que puede contener un

FernandoArielBeunza79156

489

Tesis de Grado en Ingeniera Informtica


mensaje. */ return payloadsize; }

/* Implementacin de funciones privadas. */ /* Funcin __modplcdl_detectproc__: Verifica la existencia de un mensaje recibido disponible para ser ledo. */ static void *__modplcdl_detectproc__(void *param) { /* Variables. */ int op; int result; int captureflag; size_t msgsize; modplcdl_phyaddr addr; modplcdlconn_hd *hd;

/* Identificador de operacin. */ /* Resultado de la operacin. */ /* Indicador de captura de un mensaje. */ /* Tamao del mensaje. */ /* Direccin de origen. */ /* Manejador de conexin por medio de la capa de enlace del modem PLC. */

void (*func) (void *, modplcdl_phyaddr, void *, size_t, void *); unsigned char *msg;

/* Funcin manejadora de mensajes recibidos. */ /* Puntero al mensaje recibido. */

/* Carga el manejador de interfaz con la capa de enlace del modem PLC. */ hd = (modplcdlconn_hd *) param; /* Verifica la existencia de un mensaje recibido. */ while(1) { /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->dlhd->hm))) continue; /* Verifica la recepcin de un mensaje. */ func = hd->recfun; if (!func) break; op = MODDRVDL_POLL; if (__modplcdl_sendrecv__(hd->hq, &result, sizeof(result), &op, sizeof(op))) captureflag = result; /* Recibe el mensaje. */ while(captureflag) { /* Solicita la recepcin de un mensaje. */ op = MODDRVDL_RECEIVE; if (!__modplcdl_sendrecv__(hd->hq, NULL, 0, &op, sizeof(op))) break; /* Enva la cantidad de bytes que se solicita recibir del mensaje. */ msgsize = hd->payloadsize; if (!__modplcdl_sendrecv__(hd->hq, &msgsize, sizeof(msgsize), &msgsize, sizeof(msgsize))) break; if (!msgsize) break; /* Recibe la direccin de origen del mensaje. */ if (!__modplcdl_sendrecv__(hd->hq, addr, sizeof(modplcdl_phyaddr), NULL, 0)) break;

490

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Recibe el mensaje. */ msg = (unsigned char *) malloc(msgsize * sizeof(unsigned char)); if (!msg) { captureflag = 0; break; } __modplcdl_sendrecv__(hd->hq, msg, msgsize, NULL, 0); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ pthread_mutex_unlock(&(hd->dlhd->hm)); /* Verifica si se ha detectado la recepcin de un mensaje para invocar al manejador de mensajes recibidos. */ if (captureflag) { func(hd, addr, msg, msgsize, hd->param); free(msg); } } /* Fin de ejecucin del hilo de deteccin de recepcin. */ pthread_mutex_unlock(&(hd->dlhd->hm)); pthread_exit(0); } /* Funcin __modplcdl_sendrecv__: Intercambia datos con el driver del modem PLC. */ static int __modplcdl_sendrecv__(int hq, void *outdata, size_t outsize, const void *indata, size_t insize) { /* Variables. */ size_t last; /* Cantidad de bytes enviados o recibidos. */ size_t sent; /* Cantidad de bytes enviados. */ size_t received; /* Cantidad de bytes recibidos. */

/* Enva la operacin. */ sent = 0; while((indata) && (sent < insize)) { last = write(hq, indata + sent, insize - sent); sent += last; } /* Recibe la respuesta. */ received = 0; while((outdata) && (received < outsize)) { last = read(hq, outdata + received, outsize - received); received += last; } /* xito. */ return 1; }

FernandoArielBeunza79156

491

Tesis de Grado en Ingeniera Informtica

C.4.3. Interfaz capa fsica modplcphy.so


En esta seccin se detalla el cdigo fuente de la biblioteca que implementa la interfaz con la capa fsica del modem PLC, que se compone de los siguientes archivos:

Archivo config.h: en este archivo se definen parmetros de configuracin de la biblioteca dinmica que implementa la interfaz con la capa fsica del modem PLC que no pueden ser modificados en tiempo de ejecucin. Archivo modplcphy.h: en este archivo se declaran las primitivas correspondientes al interfaz con la capa fsica. Dichas primitivas brindan un conjunto de funcionalidades que permiten la comunicacin con la capa fsica implementada en el modem PLC por medio del driver del mismo. Archivo modplcphy.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo modplcphy.h.

C.4.3.1. Archivo config.h


/* config.h Definicin de parmetros de configuracin. */

#if !defined(__CONFIG_H__) #define __CONFIG_H__

/* Interfaz con el driver del modem PLC. */ /* Cdigos de operaciones de la interfaz de la capa fsica. */ #define MODDRVPHY_RELEASE 0x00 #define MODDRVPHY_SNDFRAME 0x01 #define MODDRVPHY_CAPFRAME 0x02 #define MODDRVPHY_GETFRAME 0x03 #define MODDRVPHY_POLL 0x04 #define MODDRVPHY_RSDFRAME 0x05 #define MODDRVPHY_CLRBUFFER 0x06 #define MODDRVPHY_SENSECHANNEL 0x07 #define MODDRVPHY_GENSIGNAL 0x08 #define MODDRVPHY_TSTRECEIVE 0x09 #define MODDRVPHY_STATUS 0x0a #define MODDRVPHY_GETPAYLOADSIZE 0x0b

#endif

C.4.3.2. Archivo modplcphy.h


/* modplcphy.h: Declaracin de funciones referentes a la interfaz de la capa fsica del modem PLC. */

#if !defined(__MODPLCPHY_H__)

492

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


#define __MODPLCPHY_H__

/* Archivos includos necesarios. */ #include <pthread.h>

/* Definicin de tipos. */ /* Manejador de interfaz con la capa fsica del modem PLC. */ typedef struct { int hq; /* Manejador de cola de mensajes. */ pthread_mutex_t hm; /* Semforo de exclusin mtua. */ struct { pthread_t detectthread; /* Manejador de hilo de deteccin de recepcin. */ void (*recfun)(void *, void *); /* Funcin manejadora de tramas capturadas. */ void *param; /* Parmetros para la funcin manejadora de tramas recibidas. */ } iface[256]; /* Tabla de interfaces fsicas. */ } modplcphy_hd;

/* Definicin de constantes. */ /* Tipos de seales. */ #define MODPLCPHY_NOISESIGNAL #define MODPLCPHY_TESTSIGNAL1 #define MODPLCPHY_TESTSIGNAL2

0x01 0x02 0x03

/* Declaracin de funciones pblicas. */ /* Funcin modplcphy_init: Inicializa los recursos utilizados por la capa fsica del modem PLC. */ modplcphy_hd *modplcphy_init(int); /* Funcin modplcphy_release: Libera los recursos utilizados por la capa fsica del modem PLC. */ int modplcphy_release(modplcphy_hd *); /* Funcin modplcphy_sndframe: Enva una trama. */ size_t modplcphy_sndframe(modplcphy_hd *, unsigned char, const void *, size_t); /* Funcin modplcphy_capframe: Captura una trama. */ int modplcphy_capframe(modplcphy_hd *, unsigned char, size_t); /* Funcin modplcphy_getframe: Obtiene una trama capturada previamente. */ size_t modplcphy_getframe(modplcphy_hd *, unsigned char, void *, size_t); /* Funcin modplcphy_notify:

FernandoArielBeunza79156

493

Tesis de Grado en Ingeniera Informtica


Define una funcin manejadora de tramas capturadas. */ int modplcphy_notify(modplcphy_hd *, unsigned char, void (*func)(modplcphy_hd *, void *), void *); /* Funcin modplcphy_poll: Verifica la captura de una trama. */ int modplcphy_poll(modplcphy_hd *, unsigned char); /* Funcin modplcphy_rsdframe: Reenva una trama. */ int modplcphy_rsdframe(modplcphy_hd *, unsigned char); /* Funcin modplcphy_clrbuffer: Limpia el buffer de captura de tramas. */ int modplcphy_clrbuffer(modplcphy_hd *, unsigned char); /* Funcin modplcphy_sensechannel: Sensa el estado del canal de comunicacin. */ int modplcphy_sensechannel(modplcphy_hd *, unsigned char, unsigned char, long int); /* Funcin modplcphy_gensignal: Genera la seal especificada por medio de la capa fsica del modem PLC. */ int modplcphy_gensignal(modplcphy_hd *, unsigned char, int); /* Funcin modplcphy_tstreceive: Realiza una prueba de recepcin. */ int modplcphy_tstreceive(modplcphy_hd *, unsigned char); /* Funcin modplcphy_status: Devuelve el estado del modem PLC. */ int modplcphy_status(modplcphy_hd *); /* Funcin modplcphy_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener una trama de la capa fsica del modem PLC. */ size_t modplcphy_getpayloadsize(modplcphy_hd *, unsigned char);

#endif

C.4.3.3. Archivo modplcphy.c


/* modplcphy.c: Implementacin de funciones referentes a la interfaz de la capa fsica del modem PLC. */

/* Archivos includos necesarios. */

494

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


#include #include #include #include #include #include #include #include #include #include "config.h" <stdio.h> <stdlib.h> <unistd.h> <string.h> <pthread.h> <sys/socket.h> <sys/types.h> <sys/un.h> "modplcphy.h"

/* Declaracin de funciones privadas. */ static void *__modplcphy_detectproc__(void *); static int __modplcphy_sendrecv__(modplcphy_hd *, void *, size_t, const void *, size_t);

/* Implementacin de funciones pblicas. */ /* Funcin modplcphy_init: Inicializa los recursos utilizados por la capa fsica del modem PLC. */ modplcphy_hd *modplcphy_init(int sid) { /* Variables. */ int layer; int result; short int iface; modplcphy_hd *handle; struct sockaddr_un servaddr;

/* Capa a la que se quiere accerder. */ /* Resultado de la solicitud. */ /* Identificadores de interfaces fsicas. */ /* Manejador de interfaz con la capa fsica del modem PLC. */ /* Direccin del servidor. */

/* Crea un nuevo manejador de interfaz con la capa fsica del modem PLC. */ handle = (modplcphy_hd *) malloc(sizeof(modplcphy_hd)); if (!handle) return NULL; /* Inicializa el manejador de interfaz con la capa fsica del modem PLC. */ while(1) { /* Abre una conexin con la cola de mensajes del driver del modem PLC. */ handle->hq = socket(AF_LOCAL, SOCK_STREAM, 0); if (handle->hq < 0) break; bzero(&servaddr, sizeof(servaddr)); servaddr.sun_family = AF_LOCAL; sprintf(servaddr.sun_path, "/tmp/modemplc%i.str", sid); if (connect(handle->hq, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) break; /* Inicializa el manejador de tramas capturadas de cada una de las interfaces fsicas. */ for(iface = 0; iface < 256; iface ++) { handle->iface[iface].recfun = NULL; handle->iface[iface].param = NULL; } /* Inicializa semforo de exclusin mtua. */ if (pthread_mutex_init(&(handle->hm), NULL)) break; if (pthread_mutex_unlock(&(handle->hm))) break; /* Solicita acceder a la capa fsica del modem PLC. */ layer = 1;

FernandoArielBeunza79156

495

Tesis de Grado en Ingeniera Informtica


if (!__modplcphy_sendrecv__(handle, &result, sizeof(result), &layer, sizeof(layer))) break; if (!result) break; /* Devuelve el manejador creado. */ return handle; } /* No se pudo inicializar la interfaz con la capa fsica del modem PLC. */ pthread_mutex_destroy(&(handle->hm)); close(handle->hq); free(handle); return NULL; } /* Funcin modplcphy_release: Libera los recursos utilizados por la capa fsica del modem PLC. */ int modplcphy_release(modplcphy_hd *hd) { /* Variables. */ int op; int result; short int iface;

/* Operacin. */ /* Resultado de la operacin. */ /* Identificadores de interfaces fsicas. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Libera el manejador de captura de tramas. */ for(iface = 0; iface < 256; iface ++) modplcphy_notify(hd, (unsigned char) (iface & 0x00ff), NULL, NULL); /* Solicita la finalizacin del acceso a la capa fsica del modem PLC. */ op = MODDRVPHY_RELEASE; if (!__modplcphy_sendrecv__(hd, &result, sizeof(result), &op, sizeof(op))) return 0; if (!result) return 0; /* Libera los recursos utilizados por el semforo de exclusin mtua. */ if (pthread_mutex_destroy(&(hd->hm))) return 0; /* Libera los recursos utilizados por la interfaz con la capa fsica del modem PLC. */ close(hd->hq); free(hd); /* xito. */ return 1; } /* Funcin modplcphy_sndframe: Enva una trama. */ size_t modplcphy_sndframe(modplcphy_hd *hd, unsigned char iface, const void *frame, size_t framesize) { /* Variables. */ int op; /* Identificador de operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0;

496

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Enva una trama. */ while(1) { /* Solicita el envo de una trama. */ op = MODDRVPHY_SNDFRAME; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ if (!__modplcphy_sendrecv__(hd, NULL, 0, &iface, sizeof(iface))) break; /* Enva el tamao de la trama. */ if (!__modplcphy_sendrecv__(hd, NULL, 0, &framesize, sizeof(framesize))) break; /* Enva la trama. */ if (!__modplcphy_sendrecv__(hd, &framesize, sizeof(framesize), frame, framesize)) break; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve la cantidad de bytes enviados. */ return framesize; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ pthread_mutex_unlock(&(hd->hm)); /* No se pudo realizar el envo. */ return 0; } /* Funcin modplcphy_capframe: Captura una trama. */ int modplcphy_capframe(modplcphy_hd *hd, unsigned char iface, size_t framesize) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Solicita la captura una trama. */ result = 0; while(1) { /* Solicita la captura de una trama. */ op = MODDRVPHY_CAPFRAME; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break;

FernandoArielBeunza79156

497

Tesis de Grado en Ingeniera Informtica


/* Enva el identificador de interfaz fsica. */ if (!__modplcphy_sendrecv__(hd, NULL, 0, &iface, sizeof(iface))) break; /* Enva el tamao de la trama. */ __modplcphy_sendrecv__(hd, &result, sizeof(result), &framesize, sizeof(framesize)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve el resultado de la solicitud. */ return result; } /* Funcin modplcphy_getframe: Obtiene una trama capturada previamente. */ size_t modplcphy_getframe(modplcphy_hd *hd, unsigned char iface, void *frame, size_t framesize) { /* Variables. */ int op; /* Identificador de operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Obtiene una trama capturada previamente. */ while(1) { /* Solicita la leer una trama. */ op = MODDRVPHY_GETFRAME; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ if (!__modplcphy_sendrecv__(hd, NULL, 0, &iface, sizeof(iface))) break; /* Enva el tamao de la trama y obtiene la trama. */ if (!__modplcphy_sendrecv__(hd, frame, framesize, &framesize, sizeof(framesize))) break; /* Obtiene el tamao de la trama leda. */ if (!__modplcphy_sendrecv__(hd, &framesize, sizeof(framesize), NULL, 0)) break; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve la cantidad de bytes ledos. */ return framesize; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */

498

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


pthread_mutex_unlock(&(hd->hm)); /* No se pudo obtener la trama capturada. */ return 0; } /* Funcin modplcphy_notify: Define una funcin manejadora de tramas capturadas. */ int modplcphy_notify(modplcphy_hd *hd, unsigned char iface, void (*func)(modplcphy_hd *, void *), void *param) { /* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Si la funcin manejadora es nula y no hay ninguna funcin manejadora definida previamente no se hace nada. */ if ((!func) && (!hd->iface[iface].recfun)) return 1; /* Si la funcin manejadora no es nula y hay una funcin manejadora previamente definida actualiza la funcin manejadora. */ if ((func) && (hd->iface[iface].recfun)) { if (pthread_mutex_lock(&(hd->hm))) return 0; hd->iface[iface].recfun = (void (*)(void *, void *)) func; hd->iface[iface].param = param; if (pthread_mutex_unlock(&(hd->hm))) return 0; return 1; } /* Si la funcin manejadora es nula y hay una funcin manejadora definida previamente se elimina esta ltima. */ if ((!func) && (hd->iface[iface].recfun)) { if (pthread_mutex_lock(&(hd->hm))) return 0; hd->iface[iface].recfun = NULL; hd->iface[iface].param = param; if (pthread_mutex_unlock(&(hd->hm))) return 0; if (pthread_join(hd->iface[iface].detectthread, NULL)) return 0; return 1; } /* Si la funcin manejadora no es nula y no hay una funcin manejadora previamente definida se define la nueva funcin manejadora. */ if ((func) && (!hd->iface[iface].recfun)) { if (pthread_mutex_lock(&(hd->hm))) return 0; hd->iface[iface].recfun = (void (*)(void *, void *)) func; hd->iface[iface].param = param; if (pthread_create(&(hd->iface[iface].detectthread), NULL, __modplcphy_detectproc__, hd)) { hd->iface[iface].recfun = NULL; hd->iface[iface].param = NULL; pthread_mutex_lock(&(hd->hm)); return 0; } if (pthread_mutex_unlock(&(hd->hm))) return 0; return 1; } /* No se pudo definir la funcin manejadora de tramas capturadas. */ return 0; } /* Funcin modplcphy_poll: Verifica la captura de una trama.

FernandoArielBeunza79156

499

Tesis de Grado en Ingeniera Informtica


*/ int modplcphy_poll(modplcphy_hd *hd, unsigned char iface) { /* Variables. */ int op; int result;

/* Identificador de operacin. */ /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Verifica la captura de una trama. */ result = 0; while(1) { /* Solicita verificar la captura de una trama. */ op = MODDRVPHY_POLL; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ __modplcphy_sendrecv__(hd, &result, sizeof(result), &iface, sizeof(iface)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve el resultado de la solicitud. */ return result; } /* Funcin modplcphy_rsdframe: Reenva una trama. */ int modplcphy_rsdframe(modplcphy_hd *hd, unsigned char iface) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Reenva una trama. */ result = 0; while(1) { /* Solicita reenviar una trama. */ op = MODDRVPHY_RSDFRAME; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ __modplcphy_sendrecv__(hd, &result, sizeof(result), &iface, sizeof(iface)); break;

500

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


} /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve el resultado del reenvo de la trama. */ return result; } /* Funcin modplcphy_clrbuffer: Limpia el buffer de captura de tramas. */ int modplcphy_clrbuffer(modplcphy_hd *hd, unsigned char iface) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Limpia el buffer de captura de tramas. */ result = 0; while(1) { /* Solicita limpiar el buffer de captura de tramas. */ op = MODDRVPHY_CLRBUFFER; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ __modplcphy_sendrecv__(hd, &result, sizeof(result), &iface, sizeof(iface)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve el resultado de la limpieza del buffer. */ return result; } /* Funcin modplcphy_sensechannel: Sensa el estado del canal de comunicacin. */ int modplcphy_sensechannel(modplcphy_hd *hd, unsigned char iface, unsigned char level, long int waittime) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0;

FernandoArielBeunza79156

501

Tesis de Grado en Ingeniera Informtica


/* Solicita el sensado del canal de comunicacin. */ result = 0; while(1) { /* Solicita el sensado del estado del canal de comunicacin. */ op = MODDRVPHY_SENSECHANNEL; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ if (!__modplcphy_sendrecv__(hd, NULL, 0, &iface, sizeof(iface))) break; /* Enva el nivel de seal. */ if (!__modplcphy_sendrecv__(hd, NULL, 0, &level, sizeof(level))) break; /* Enva el tiempo de espera. */ __modplcphy_sendrecv__(hd, &result, sizeof(result), &waittime, sizeof(waittime)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve el resultado del sensado del estado del canal de comunicacin. */ return result; } /* Funcin modplcphy_gensignal: Genera la seal especificada por medio de la capa fsica del modem PLC. */ int modplcphy_gensignal(modplcphy_hd *hd, unsigned char iface, int sig) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Solicita la generacin de la seal especificada. */ result = 0; while(1) { /* Solicita la generacin de una seal. */ op = MODDRVPHY_GENSIGNAL; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ if (!__modplcphy_sendrecv__(hd, NULL, 0, &iface, sizeof(iface))) break; /* Enva el tipo de seal. */ __modplcphy_sendrecv__(hd, &result, sizeof(result), &sig, sizeof(sig));

502

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve el resultado de la solicitud. */ return result; } /* Funcin modplcphy_tstreceive: Realiza una prueba de recepcin. */ int modplcphy_tstreceive(modplcphy_hd *hd, unsigned char iface) { /* Variables. */ int op; /* Identificador de operacin. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Realiza una prueba de recepcin. */ result = 0; while(1) { /* Solicita realizar una prueba de recepcin. */ op = MODDRVPHY_TSTRECEIVE; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ __modplcphy_sendrecv__(hd, &result, sizeof(result), &iface, sizeof(iface)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve el resultado de la prueba de recepcin. */ return result; } /* Funcin modplcphy_status: Devuelve el estado del modem PLC. */ int modplcphy_status(modplcphy_hd *hd) { /* Variables. */ int op; int result;

/* Identificador de operacin. */ /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0;

FernandoArielBeunza79156

503

Tesis de Grado en Ingeniera Informtica


/* Obtiene el estado del modem PLC. */ op = MODDRVPHY_STATUS; if (!__modplcphy_sendrecv__(hd, &result, sizeof(result), &op, sizeof(op))) result = 0; /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve el estado del modem PLC. */ return result; } /* Funcin modplcphy_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener una trama de la capa fsica del modem PLC. */ size_t modplcphy_getpayloadsize(modplcphy_hd *hd, unsigned char iface) { /* Variables. */ int op; /* Operacin. */ size_t payloadsize; /* Cantidad de bytes que puede contener una trama. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) return 0; /* Devuelve la cantidad mxima de bytes que puede contener una trama. */ payloadsize = 0; while(1) { /* Obtiene la cantidad mxima de bytes que puede contener una trama. */ op = MODDRVPHY_GETPAYLOADSIZE; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ __modplcphy_sendrecv__(hd, &payloadsize, sizeof(payloadsize), &iface, sizeof(iface)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_unlock(&(hd->hm))) return 0; /* Devuelve la cantidad mxima de bytes que puede contener una trama. */ return payloadsize; }

/* Implementacin de funciones privadas. */ /* Funcin __modplcphy_detectproc__: Verifica la existencia de una trama capturada disponible para ser leda. */ static void *__modplcphy_detectproc__(void *param) { /* Variables. */

504

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


int op; int captureflag; short int i; unsigned char iface; modplcphy_hd *hd; void (*func)(void *, void *); /* Identificador de operacin. */ /* Indicador de captura de una trama. */ /* Contador. */ /* Identificadores de interfaces fsicas. */ /* Manejador de interfaz con la capa fsica del modem PLC. */ /* Manejador de captura de tramas. */

/* Carga el manejador de interfaz con la capa fsica del modem PLC. */ hd = (modplcphy_hd *) param; /* Obtiene el identificador de interface fsica asociado al hilo de deteccin de recepcin. */ iface = 0; if (pthread_mutex_lock(&(hd->hm))) return 0; for(i = 0; i < 256; i++) { if (!pthread_equal(hd->iface[i].detectthread, pthread_self())) continue; iface = (unsigned char) (i & 0x00ff); break; } pthread_mutex_unlock(&(hd->hm)); if (i > 255) return 0; /* Verifica la existencia de una trama capturada. */ while(1) { /* Espera el permiso para poder comunicarse con el driver del modem PLC. */ if (pthread_mutex_lock(&(hd->hm))) continue; /* Verifica la captura de una trama. */ func = hd->iface[iface].recfun; if (!func) break; captureflag = 0; while(1) { /* Solicita verificar la captura de una trama. */ op = MODDRVPHY_POLL; if (!__modplcphy_sendrecv__(hd, NULL, 0, &op, sizeof(op))) break; /* Enva el identificador de interfaz fsica. */ __modplcphy_sendrecv__(hd, &captureflag, sizeof(captureflag), &iface, sizeof(iface)); break; } /* Permite a otro hilos poder comunicarse con el driver del modem PLC. */ pthread_mutex_unlock(&(hd->hm)); /* Verifica si se ha detectado la captura de una trama para invocar al manejador de trama capturadas. */ if (captureflag) func(hd, hd->iface[iface].param); } /* Fin de ejecucin del hilo de deteccin de recepcin. */ pthread_mutex_unlock(&(hd->hm)); pthread_exit(0); } /* Funcin __modplcphy_sendrecv__: Intercambia datos con el driver del modem PLC.

FernandoArielBeunza79156

505

Tesis de Grado en Ingeniera Informtica


*/ static int __modplcphy_sendrecv__(modplcphy_hd *hd, void *outdata, size_t outsize, const void *indata, size_t insize) { /* Variables. */ size_t last; /* Cantidad de bytes enviados o recibidos. */ size_t sent; /* Cantidad de bytes enviados. */ size_t received; /* Cantidad de bytes recibidos. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Enva la operacin. */ sent = 0; while((indata) && (sent < insize)) { last = write(hd->hq, indata + sent, insize - sent); sent += last; } /* Recibe la respuesta. */ received = 0; while((outdata) && (received < outsize)) { last = read(hd->hq, outdata + received, outsize - received); received += last; } /* xito. */ return 1; }

C.4.4. Driver del Modem PLC modem_driver


En esta seccin se detalla el cdigo fuente del driver del modem PLC, que se compone de los siguientes archivos:

Archivo config.h: en este archivo se definen parmetros de configuracin del driver del del modem PLC que no pueden ser modificados en tiempo de ejecucin. Archivo serial.h: en este archivo se declaran primitivas con funcionalidades referentes a la comunicacin por puerto serie. Archivo serial.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo serial.h. Archivo modplc.h: en este archivo se declaran las primitivas correspondientes al interfaz con la capa fsica, de enlace y de sesin. Dichas primitivas brindan un conjunto de funcionalidades que permiten la comunicacin con las capas mencionadas implementadas en el modem PLC. Archivo modplc.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo modplc.h.

506

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Archivo modsp.h: en este archivo se declaran las primitivas correspondientes al interfaz con la capa de sesin. Dichas primitivas brindan un conjunto de funcionalidades que permiten la comunicacin con las capa de sesin implementada en el modem PLC. Archivo modsp.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo modsp.h. Archivo moddl.h: en este archivo se declaran las primitivas correspondientes al interfaz con la capa de enlace. Dichas primitivas brindan un conjunto de funcionalidades que permiten la comunicacin con las capa de enlace implementada en el modem PLC. Archivo moddl.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo moddl.h. Archivo modphy.h: en este archivo se declaran las primitivas correspondientes al interfaz con la capa fsica. Dichas primitivas brindan un conjunto de funcionalidades que permiten la comunicacin con las capa fsica implementada en el modem PLC. Archivo modphy.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo modphy.h. Archivo moddrv.h: en este archivo se declaran las primitivas correspondientes al driver del modem PLC. Dichas primitivas brindan un conjunto de funcionalidades que permite a las interfaces mencionadas anteriormente comunicarse con el modem PLC. Archivo moddrv.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo moddrv.h. Archivo modem_driver.c: en este archivo se encuentra implementada la inicializacin de la ejecucin del driver del modem PLC.

C.4.4.1. Archivo config.h


/* config.h Definicin de parmetros de configuracin. */

#if !defined(__CONFIG_H__) #define __CONFIG_H__

/* Interfaz del modem PLC. */ /* Tipos de prompt utilizados. */ #define MODPLC_INITPROMPT #define MODPLC_LAYPROMPT #define MODPLC_NORMPROMPT #define MODPLC_PARAMPROMPT /* Tipos de reset. */ #define MODPLC_NORMRESET #define MODPLC_PARAMRESET

'#' '?' '$' '>'

'0' '$'

FernandoArielBeunza79156

507

Tesis de Grado en Ingeniera Informtica


/* Cdigo de operaciones de la capa fsica. */ #define MODPLCPHY_RESET #define MODPLCPHY_SNDFRAME #define MODPLCPHY_CAPFRAME #define MODPLCPHY_GETFRAME #define MODPLCPHY_POLL #define MODPLCPHY_RSDFRAME #define MODPLCPHY_CLRBUFFER #define MODPLCPHY_SENSECHANNEL #define MODPLCPHY_GENSIGNAL #define MODPLCPHY_TSTRECEIVE #define MODPLCPHY_GETPAYLOADSIZE /* Tipos de seal. */ #define MODPLCPHY_NOISESIGNAL #define MODPLCPHY_TESTSIGNAL1 #define MODPLCPHY_TESTSIGNAL2 /* Cdigo de operaciones de la capa de enlace. */ #define MODPLCDL_RESET #define MODPLCDL_OPEN #define MODPLCDL_CLOSE #define MODPLCDL_SEND #define MODPLCDL_RECEIVE #define MODPLCDL_POLL #define MODPLCDL_GETADDRESS #define MODPLCDL_ADDLOGADDRESS #define MODPLCDL_DELLOGADDRESS #define MODPLCDL_GETPHYADDRESS #define MODPLCDL_GETPAYLOADSIZE /* Cdigo de operaciones de la capa de sesin. */ #define MODPLCSP_RESET #define MODPLCSP_PUBLISH #define MODPLCSP_SUBSCRIBE #define MODPLCSP_LEAVE #define MODPLCSP_SEND #define MODPLCSP_RECEIVE #define MODPLCSP_POLL #define MODPLCSP_GETPAYLOADSIZE MODPLC_NORMRESET '1' '2' '3' '4' '5' '6' '7' '8' '9' 'a'

0x01 0x02 0x03

MODPLC_NORMRESET '1' '2' '3' '4' '5' '6' '7' '8' '9' 'a'

MODPLC_NORMRESET '1' '2' '3' '4' '5' '6' '7'

/* Driver del modem PLC. */ /* Cdigos de operaciones de la interfaz de la capa fsica. */ #define MODDRVPHY_RELEASE 0x00 #define MODDRVPHY_SNDFRAME 0x01 #define MODDRVPHY_CAPFRAME 0x02 #define MODDRVPHY_GETFRAME 0x03 #define MODDRVPHY_POLL 0x04 #define MODDRVPHY_RSDFRAME 0x05 #define MODDRVPHY_CLRBUFFER 0x06 #define MODDRVPHY_SENSECHANNEL 0x07 #define MODDRVPHY_GENSIGNAL 0x08 #define MODDRVPHY_TSTRECEIVE 0x09 #define MODDRVPHY_STATUS 0x0a #define MODDRVPHY_GETPAYLOADSIZE 0x0b /* Cdigos de operaciones de la interfaz de la capa de enlace. */ #define MODDRVDL_CLOSE 0x00 #define MODDRVDL_OPEN 0x01 #define MODDRVDL_SEND 0x02 #define MODDRVDL_RECEIVE 0x03 #define MODDRVDL_POLL 0x04 #define MODDRVDL_GETADDRESS 0x05 #define MODDRVDL_ADDLOGADDRESS 0x06 #define MODDRVDL_DELLOGADDRESS 0x07 #define MODDRVDL_GETPHYADDRESS 0x08 #define MODDRVDL_STATUS 0x09 #define MODDRVDL_GETPAYLOADSIZE 0x0a

508

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Cdigos de operaciones de la interfaz de la capa de sesin. */ #define MODDRVSP_RELEASE 0x00 #define MODDRVSP_PUBLISH 0x01 #define MODDRVSP_SUBSCRIBE 0x02 #define MODDRVSP_LEAVE 0x03 #define MODDRVSP_SEND 0x04 #define MODDRVSP_RECEIVE 0x05 #define MODDRVSP_POLL 0x06 #define MODDRVSP_STATUS 0x07 #define MODDRVSP_GETPAYLOADSIZE 0x08

/* Interfaz con el modem PLC. */ /* Tamaoo del buffer. */ #define MODPLC_BUFFERSIZE /* Cantidad de bytes de una lnea por envo. */ #define MODPLC_FRAGMENTLINESIZE

4096

#endif

C.4.4.2. Archivo serial.h


/* serial.h: Declaracin de funciones referentes a la interfaz de comunicacin por puerto serie. */

#if !defined(__SERIAL_H__) #define __SERIAL_H__

/* Archivos includos necesarios. */ #include "config.h" #include <stdlib.h> #include <termios.h>

/* Definicin de tipos. */ /* Manejador de interfaz de comunicacin por puerto serie. */ typedef struct { int serialhd; /* Manejador de interfaz de puerto serie. */ struct termios oldtio; /* Antigua configuracin de la interfaz de puerto serie. */ struct termios newtio; /* Nueva configuracin de la interfaz de puerto serie. */ } serial_hd;

/* Declaracin de funciones pblicas. */ /* Funcin serial_init: Inicializa la interfaz de comunicacin por puerto serie. */ serial_hd *serial_init(int); /* Funcin serial_release: Libera los recursos utilizdos por la interfaz de comunicacin por puerto serie.

FernandoArielBeunza79156

509

Tesis de Grado en Ingeniera Informtica


*/ int serial_release(serial_hd *); /* Funcin serial_send: Enva un mensaje a travs de la interfaz de comunicacin por puerto serie. */ size_t serial_send(serial_hd *, const void *, size_t); /* Funcin serial_receive: Recibe un mensaje a por medio de la interfaz de comunicacin por puerto serie. */ size_t serial_receive(serial_hd *, void *, size_t); /* Funcin serial_poll: Devuelve si hay un mensaje a la espera de ser recibido. */ int serial_poll(serial_hd *);

#endif

C.4.4.3. Archivo serial.c


/* serial.c: Implementacin de funciones referentes a la interfaz de comunicacin por puerto serie. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdio.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <termios.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include "serial.h"

/* Implementacin de funciones pblicas. */ /* Funcin serial_init: Inicializa la interfaz de comunicacin por puerto serie. */ serial_hd *serial_init(int id) { /* Variables. */ serial_hd *handle; char iname[256];

/* Manejador de la interfaz. */ /* Nombre de la interfaz. */

/* Verifica la validez del identificador de la interfaz de comunicacin por puerto serie. */ if (id < 1) return 0; /* Crea un nuevo manejador de interfaz de comunicacin por puerto serie. */ handle = (serial_hd *) malloc(sizeof(serial_hd)); if (!handle) return NULL;

510

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Inicializa la interfaz de comunicacin por puerto serie. */ while(1) { /* Abre la interfaz de comunicacin por puerto serie. */ if (id < 15) sprintf(iname, "/dev/ttyS%i", id - 1); else sprintf(iname, "/dev/ttyUSB%i", id - 15); handle->serialhd = open(iname, O_RDWR | O_NOCTTY | O_NONBLOCK); if (handle->serialhd < 0) break; /* Configura la interfaz de comunicacin por puerto serie. */ tcgetattr(handle->serialhd, &(handle->oldtio)); handle->newtio.c_cflag = B57600 | CS8 | CLOCAL | CREAD; handle->newtio.c_iflag = IGNPAR; handle->newtio.c_oflag = 0; handle->newtio.c_lflag = 0; tcflush(handle->serialhd, TCIFLUSH); tcsetattr(handle->serialhd, TCSANOW, &(handle->newtio)); /* Devuelve el manejador de la interfaz de comunicacin por puerto serie. */ return handle; } /* No se pudo inicializar la interfaz de comunicacin por puerto serie. */ free(handle); return NULL; } /* Funcin serial_release: Libera los recursos utilizdos por la interfaz de comunicacin por puerto serie. */ int serial_release(serial_hd *hd) { /* Verifica la validez del manejador de la interfaz de comunicacin por puerto serie. */ if (!hd) return 0; /* Restaura la antigua configuracin de la interfaz de comunicacin por puerto serie. */ tcsetattr(hd->serialhd, TCSANOW, &(hd->oldtio)); /* Libera los recursos utilizados por la interfaz de comunicacin por puerto serie. */ close(hd->serialhd); free(hd); /* xito. */ return 1; } /* Funcin serial_send: Enva un mensaje a travs de la interfaz de comunicacin por puerto serie. */ size_t serial_send(serial_hd *hd, const void *msg, size_t msgsize) { /* Variables. */ size_t sent; /* Cantidad de bytes enviados. */ unsigned char *ptr; /* Puntero al mensaje. */

/* Verifica la validez del manejador de la interfaz de comunicacin por puerto serie. */ if (!hd) return 0; /* Enva un mensaje. */ sent = 0;

FernandoArielBeunza79156

511

Tesis de Grado en Ingeniera Informtica


ptr = (unsigned char *) msg; usleep(10000UL); while(sent < msgsize) sent += write(hd->serialhd, ptr + sent, msgsize - sent); /* Devuelve la cantidad de bytes enviados. */ return sent; } /* Funcin serial_receive: Recibe un mensaje por medio de la interfaz de comunicacin por puerto serie. */ size_t serial_receive(serial_hd *hd, void *msg, size_t msgsize) { /* Verifica la validez del manejador de la interfaz de comunicacin por puerto serie. */ if (!hd) return 0; /* Espera a que el buffer de recepcin tenga algn contenido. */ usleep(10000UL); while(!serial_poll(hd)); /* Recibe un mensaje. */ return read(hd->serialhd, (unsigned char *) msg, msgsize); } /* Funcin serial_poll: Verifica la llegada de un nuevo mensaje. */ int serial_poll(serial_hd *hd) { /* Variables. */ size_t received;

/* Cantidad de bytes almacenados en el buffer de entrada. */

/* Verifica la validez del manejador de la interfaz de comunicacin por puerto serie. */ if (!hd) return 0; /* Verifica si el buffer no se encuentra vaco. */ ioctl(hd->serialhd, FIONREAD, &received); return (received != 0); }

C.4.4.4. Archivo modplc.h


/* modplc.h: Declaracin de funciones referentes a la interfaz con el modem PLC. */

#if !defined(__MODPLC_H__) #define __MODPLC_H__

/* Archivos includos necesarios. */ #include "config.h" #include "serial.h"

/* Definicin de tipos. */ /* Direccin fsica del modem PLC. */

512

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


typedef unsigned char modplc_dlphyaddr[8]; /* Direccin lgica del modem PLC. */ typedef unsigned long int modplc_dllogaddr; /* Identificador de grupo. */ typedef unsigned char modplc_spgrpid; /* Manejador de interfaz con el modem PLC. */ typedef struct { serial_hd *serialhd;

int layer; int status; int debugmode; } modplc_hd;

/* Manejador de interfaz de comunicacin por puerto serie. */ /* Capa del modem PLC utilizada. */ /* Estado del modem PLC. */ /* Indicador de modo depuracin. */

/* Definicin de constantes. */ /* Capas de acceso. */ #define MODPLC_PHYSICALLAYER #define MODPLC_DATALINKLAYER #define MODPLC_SESSIONLAYER /* Tipos de seales. */ #define MODPLC_PHYNOISESIGNAL #define MODPLC_PHYTESTSIGNAL1 #define MODPLC_PHYTESTSIGNAL2

0x01 0x02 0x03

0x01 0x02 0x03

/* Declaracin de funciones pblicas. */ /* Funcin modplc_init: Inicializa los recursos utilizados por la interfaz con el modem PLC. */ modplc_hd *modplc_init(int, int, int); /* Funcin modplc_release: Libera los recursos utilizados por la interfaz con el modem PLC. */ int modplc_release(modplc_hd *); /* Funcin modplc_status: Devuelve el estado del modem PLC. */ int modplc_status(modplc_hd *); /* Funcin modplc_physndframe: Enva una trama por medio de la capa fsica del modem PLC. */ size_t modplc_physndframe(modplc_hd *, unsigned char, const void *, size_t); /* Funcin modplc_phycapframe: Captura una trama por medio de la capa fsica del modem PLC. */ int modplc_phycapframe(modplc_hd *, unsigned char, size_t); /* Funcin modplc_phygetframe: Obtiene una trama capturada previamente por medio de la capa fsica del modem PLC. */ size_t modplc_phygetframe(modplc_hd *, unsigned char, void *, size_t);

FernandoArielBeunza79156

513

Tesis de Grado en Ingeniera Informtica


/* Funcin phy_poll: Verifica la captura de una trama por medio de la capa fsica del modem PLC. */ int modplc_phypoll(modplc_hd *, unsigned char); /* Funcin modplc_phyrsdframe: Reenva una trama por medio de la capa fsica del modem PLC. */ int modplc_phyrsdframe(modplc_hd *, unsigned char); /* Funcin modplc_phyclrbuffer: Limpia el buffer de captura de tramas de la capa fsica del modem PLC. */ int modplc_phyclrbuffer(modplc_hd *, unsigned char); /* Funcin modplc_physensechannel: Sensa el estado del canal de comunicacin por medio de la capa fsica del modem PLC. */ int modplc_physensechannel(modplc_hd *, unsigned char, unsigned char, long int); /* Funcin modplc_phygensignal: Genera la seal especificada por medio de la capa fsica del modem PLC. */ int modplc_phygensignal(modplc_hd *, unsigned char, int); /* Funcin modplc_phytstreceive: Realiza una prueba de recepcin de la capa fsica del modem PLC. */ int modplc_phytstreceive(modplc_hd *, unsigned char); /* Funcin modplc_phygetpayloadsize: Devuelve la cantidad mxima de bytes que puede contener una trama de la capa fsica del modem PLC. */ size_t modplc_phygetpayloadsize(modplc_hd *, unsigned char); /* Funcin modplc_dlopen: Abre una conexin por medio de la capa de enlace del modem PLC. */ int modplc_dlopen(modplc_hd *, unsigned char, unsigned char); /* Funcin modplc_dlclose: Cierra una conexin por medio de la capa de enlace del modem PLC. */ int modplc_dlclose(modplc_hd *, int); /* Funcin modplc_dlsend: Enva un mensaje por medio de la capa de enlace del modem PLC. */ size_t modplc_dlsend(modplc_hd *, int, modplc_dlphyaddr, unsigned char, const void *, size_t); /* Funcin modplc_dlreceive: Recibe un mensaje por medio de la capa de enlace del modem PLC. */ size_t modplc_dlreceive(modplc_hd *, int, modplc_dlphyaddr, void *, size_t);

514

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin modplc_dlpoll: Verifica la llegada de un nuevo mensaje por medio de la capa de enlace del modem PLC. */ int modplc_dlpoll(modplc_hd *, int); /* Funcin modplc_dlgetaddress: Devuelve la direccin fsica de la capa de enlace del modem PLC. */ int modplc_dlgetaddress(modplc_hd *, unsigned char, modplc_dlphyaddr); /* Funcin modplc_dladdlogaddress: Agrega una nueva direccin lgica a la capa de enlace del modem PLC. */ int modplc_dladdlogaddress(modplc_hd *, unsigned char, unsigned char, modplc_dllogaddr); /* Funcin modplc_dldellogaddress: Elimina una direccin lgica a la capa de enlace del modem PLC. */ int modplc_dldellogaddress(modplc_hd *, unsigned char, unsigned char, modplc_dllogaddr); /* Funcin modplc_dlgetphyaddress: Devuelve la direccin fsica asociada a la direccin lgica de la capa de enlace del modem PLC. */ int modplc_dlgetphyaddress(modplc_hd *, unsigned char, unsigned char, modplc_dllogaddr, modplc_dlphyaddr); /* Funcin modplc_dlgetpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de enlace del modem PLC. */ size_t modplc_dlgetpayloadsize(modplc_hd *, unsigned char); /* Funcin modplc_sppublish: Registra el dispositivo como publicador del grupo de difusin especificado de la capa de sesin del modem PLC. */ int modplc_sppublish(modplc_hd *, modplc_spgrpid); /* Funcin modplc_spsubscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado de la capa de sesin del modem PLC. */ int modplc_spsubscribe(modplc_hd *, modplc_spgrpid); /* Funcin modplc_spleave: Desvincula el dispositivo del grupo de difusin especificado de la capa de sesin del modem PLC. */ int modplc_spleave(modplc_hd *, modplc_spgrpid); /* Funcin modplc_spsend: Enva un mensaje por medio de la capa de sesin del modem PLC. */ size_t modplc_spsend(modplc_hd *, modplc_spgrpid, int, const void *, size_t); /*

FernandoArielBeunza79156

515

Tesis de Grado en Ingeniera Informtica


Funcin modplc_spreceive: Recibe un mensaje por medio de la capa de sesin del modem PLC. */ size_t modplc_spreceive(modplc_hd *, modplc_spgrpid *, void *, size_t); /* Funcin modplc_sppoll: Verifica la llegada de un nuevo mensaje por medio de la capa de sesin del modem PLC. */ int modplc_sppoll(modplc_hd *); /* Funcin modplc_spgetpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de sesin del modem PLC. */ size_t modplc_spgetpayloadsize(modplc_hd *);

#endif

C.4.4.5. Archivo modplc.c


/* modplc.c: Implementacin de funciones referentes a la interfaz con el modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdio.h> #include <unistd.h> #include <string.h> #include "serial.h" #include "modplc.h"

/* Declaracin de funciones privadas. */ static char __modplc_sendcmdline__(modplc_hd *, const char *, char *, size_t); static int __modplc_sendcmd__(modplc_hd *, char, const char *, void **, const void *, const char *, void **, void *);

/* Implementacin de funciones pblicas. */ /* Funcin modplc_init: Inicializa los recursos utilizados por la interfaz con el modem PLC. */ modplc_hd *modplc_init(int sid, int layer, int debugmode) { /* Variables. */ char prompt; modplc_hd *handle; char cmdline[MODPLC_BUFFERSIZE]; char respline[MODPLC_BUFFERSIZE];

/* Smbolo de la lnea de comando. */ /* Manejador de interfaz con el modem PLC. */ /* Lnea de comando. */ /* Lnea de respuesta de comando. */

/* Crea un nuevo manejador de interfaz con el modem PLC. */ handle = (modplc_hd *) malloc(sizeof(modplc_hd)); if (!handle) return NULL; /* Inicializa la interfaz de comunicacin por puerto serie. */

516

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


handle->serialhd = serial_init(sid); if (!handle->serialhd) { free(handle); return NULL; } /* Si es requerido establece el modo depuracin. */ handle->debugmode = 0; if (debugmode) handle->debugmode = 1; /* Inicializa la interfaz con el modem PLC. */ while(1) { /* Inicializa el modem PLC. */ *(cmdline + 0) = '\n'; *(cmdline + 1) = 0; prompt = __modplc_sendcmdline__(handle, cmdline, respline, MODPLC_BUFFERSIZE); if (prompt == MODPLC_INITPROMPT) sprintf(cmdline, "reset"); else if (prompt == MODPLC_LAYPROMPT) { *(cmdline + 0) = MODPLC_NORMRESET; *(cmdline + 1) = 0; } else if (prompt == MODPLC_NORMPROMPT) { *(cmdline + 0) = MODPLC_NORMRESET; *(cmdline + 1) = 0; } else if (prompt == MODPLC_PARAMPROMPT) { *(cmdline + 0) = MODPLC_PARAMRESET; *(cmdline + 1) = 0; } else break; strcat(cmdline, "\n"); if (__modplc_sendcmdline__(handle, cmdline, respline, MODPLC_BUFFERSIZE) != MODPLC_INITPROMPT) break; sprintf(cmdline, "init\n"); if (__modplc_sendcmdline__(handle, cmdline, respline, MODPLC_BUFFERSIZE) != MODPLC_LAYPROMPT) break; /* Establece la capa a la cual se quiere acceder. */ handle->layer = layer; if (handle->layer == MODPLC_PHYSICALLAYER) *(cmdline + 0) = MODPLC_PHYSICALLAYER + '0'; else if (handle->layer == MODPLC_DATALINKLAYER) *(cmdline + 0) = MODPLC_DATALINKLAYER + '0'; else if (handle->layer == MODPLC_SESSIONLAYER) *(cmdline + 0) = MODPLC_SESSIONLAYER + '0'; else break; *(cmdline + 1) = '\n'; *(cmdline + 2) = 0; if (__modplc_sendcmdline__(handle, cmdline, respline, MODPLC_BUFFERSIZE) != MODPLC_NORMPROMPT) break; /* Modem PLC en estado activo. */ handle->status = 1; /* Devuelve el manejador creado. */ return handle; } /* No se pudo inicializar la interfaz con el modem PLC. */

FernandoArielBeunza79156

517

Tesis de Grado en Ingeniera Informtica


modplc_release(handle); return NULL; } /* Funcin modplc_release: Libera los recursos utilizados por la interfaz con el modem PLC. */ int modplc_release(modplc_hd *hd) { /* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Libera la interfaz de comunicacin por puerto serie. */ serial_release(hd->serialhd); /* Libera los recursos utilizados por la interfaz con el modem PLC. */ free(hd); /* xito. */ return 1; } /* Funcin modplc_status: Devuelve el estado del modem PLC. */ int modplc_status(modplc_hd *hd) { /* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que el modem PLC se encuentre activo. */ if (!hd->status) return 0; if (__modplc_sendcmdline__(hd, "\n", NULL, MODPLC_BUFFERSIZE) == MODPLC_NORMPROMPT) return 1; hd->status = 0; return 0; } /* Funcin modplc_physndframe: Enva una trama por medio de la capa fsica del modem PLC. */ size_t modplc_physndframe(modplc_hd *hd, unsigned char iface, const void *frame, size_t framesize) { /* Variables. */ void *inparam[2]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Enva una trama. */ inparam[0] = &iface; inparam[1] = &framesize; outparam[0] = &framesize; if (__modplc_sendcmd__(hd, MODPLCPHY_SNDFRAME, "bs", inparam, frame, "s", outparam, NULL)) return framesize; return 0; }

518

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin modplc_phycapframe: Captura una trama por medio de la capa fsica del modem PLC. */ int modplc_phycapframe(modplc_hd *hd, unsigned char iface, size_t framesize) { /* Variables. */ unsigned char result; /* Resultado del comando. */ void *inparam[2]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Captura una trama. */ inparam[0] = &iface; inparam[1] = &framesize; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCPHY_CAPFRAME, "bs", inparam, NULL, "b", outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_phygetframe: Obtiene una trama capturada previamente por medio de la capa fsica del modem PLC. */ size_t modplc_phygetframe(modplc_hd *hd, unsigned char iface, void *frame, size_t framesize) { /* Variables. */ void *inparam[2]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Obtiene una trama capturada. */ inparam[0] = &iface; inparam[1] = &framesize; outparam[0] = &framesize; if (__modplc_sendcmd__(hd, MODPLCPHY_GETFRAME, "bs", inparam, NULL, "s", outparam, frame)) return framesize; return 0; } /* Funcin modplc_phypoll: Verifica la captura de una trama por medio de la capa fsica del modem PLC. */ int modplc_phypoll(modplc_hd *hd, unsigned char iface) { /* Variables. */ unsigned char result; void *inparam[1];

/* Resultado del comando. */ /* Parmetros de entrada del

FernandoArielBeunza79156

519

Tesis de Grado en Ingeniera Informtica


void *outparam[1]; comando. */ /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Verifica la captura de una trama. */ inparam[0] = &iface; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCPHY_POLL, "b", inparam, NULL, outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_phyrsdframe: Reenva una trama por medio de la capa fsica del modem PLC. */ int modplc_phyrsdframe(modplc_hd *hd, unsigned char iface) { /* Variables. */ unsigned char result; /* Resultado del comando. */ void *inparam[1]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

"b",

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Reenva una trama. */ inparam[0] = &iface; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCPHY_RSDFRAME, "b", inparam, NULL, "b", outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_phyclrbuffer: Limpia el buffer de captura de tramas de la capa fsica del modem PLC. */ int modplc_phyclrbuffer(modplc_hd *hd, unsigned char iface) { /* Variables. */ unsigned char result; /* Resultado del comando. */ void *inparam[1]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Limpia el buffer de captura de tramas. */ inparam[0] = &iface;

520

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCPHY_CLRBUFFER, "b", inparam, NULL, "b", outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_physensechannel: Sensa el estado del canal de comunicacin por medio de la capa fsica del modem PLC. */ int modplc_physensechannel(modplc_hd *hd, unsigned char iface, unsigned char level, long int waittime) { /* Variables. */ unsigned char result; /* Resultado del comando. */ void *inparam[3]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Sensa el estado del canal de comunicacin. */ inparam[0] = &iface; inparam[1] = &level; inparam[2] = &waittime; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCPHY_SENSECHANNEL, "bbl", inparam, NULL, "b", outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_phygensignal: Genera la seal especificada por medio de la capa fsica del modem PLC. */ int modplc_phygensignal(modplc_hd *hd, unsigned char iface, int sig) { /* Variables. */ unsigned char result; /* Resultado del comando. */ void *inparam[2]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Genera la seal especificada. */ inparam[0] = &iface; inparam[1] = &sig; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCPHY_GENSIGNAL, "bb", inparam, NULL, "b", outparam, NULL)) return (result == 1); return 0; } /*

FernandoArielBeunza79156

521

Tesis de Grado en Ingeniera Informtica


Funcin modplc_phytstreceive: Realiza una prueba de recepcin de la capa fsica del modem PLC. */ int modplc_phytstreceive(modplc_hd *hd, unsigned char iface) { /* Variables. */ unsigned char result; /* Resultado del comando. */ void *inparam[1]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Realiza una prueba de recepcin. */ inparam[0] = &iface; outparam[0] = &result; if (__modplc_sendcmd__(hd, MODPLCPHY_TSTRECEIVE, "b", inparam, NULL, "b", outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_phygetpayloadsize: Devuelve la cantidad mxima de bytes que puede contener una trama de la capa fsica del modem PLC. */ size_t modplc_phygetpayloadsize(modplc_hd *hd, unsigned char iface) { /* Variables. */ unsigned short int payloadsize; /* Cantidad mxima de bytes que puede contener una trama. */ void *inparam[1]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa fsica. */ if (hd->layer != MODPLC_PHYSICALLAYER) return 0; /* Devuelve la cantidad mxima de byes que puede contener una trama. */ inparam[0] = &iface; outparam[0] = &payloadsize; if (__modplc_sendcmd__(hd, MODPLCPHY_GETPAYLOADSIZE, "b", inparam, NULL, "s", outparam, NULL)) return (size_t) payloadsize; return 0; } /* Funcin modplc_dlopen: Abre una conexin por medio de la capa de enlace del modem PLC. */ int modplc_dlopen(modplc_hd *hd, unsigned char iface, unsigned char prot) { /* Variables. */ unsigned short int handle; /* Manejador de conexin. */ void *inparam[2]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

522

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0; /* Abre una conexin. */ inparam[0] = &iface; inparam[1] = &prot; outparam[0] = &handle; if (__modplc_sendcmd__(hd, '1', "bb", inparam, NULL, NULL)) return (int) handle; return 0; } /* Funcin modplc_dlclose: Cierra una conexin por medio de la capa de enlace del modem PLC. */ int modplc_dlclose(modplc_hd *hd, int handle) { /* Variables. */ unsigned char result; void *inparam[2]; void *outparam[1];

"s", outparam,

/* Resultado del comando. */ /* Parmetros de entrada del comando. */ /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0; /* Cierra una conexin. */ inparam[0] = &handle; outparam[0] = &result; if (__modplc_sendcmd__(hd, '2', "s", inparam, NULL, NULL)) return (result == 1); return 0; } /* Funcin modplc_dlsend: Enva un mensaje por medio de la capa de enlace del modem PLC. */ size_t modplc_dlsend(modplc_hd *hd, int handle, modplc_dlphyaddr addr, unsigned char prio, const void *msg, size_t msgsize) { /* Variables. */ void *inparam[4]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

"b", outparam,

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0; /* Enva un mensaje. */ inparam[0] = &handle; inparam[1] = addr; inparam[2] = &prio;

FernandoArielBeunza79156

523

Tesis de Grado en Ingeniera Informtica


inparam[3] = &msgsize; outparam[0] = &msgsize; if (__modplc_sendcmd__(hd, '3', "sabs", inparam, msg, NULL)) return msgsize; return 0; } /* Funcin modplc_dlreceive: Recibe un mensaje por medio de la capa de enlace del modem PLC. */ size_t modplc_dlreceive(modplc_hd *hd, int handle, modplc_dlphyaddr addr, void *msg, size_t msgsize) { /* Variables. */ void *inparam[2]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

"s", outparam,

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0; /* Recibe un mensaje. */ inparam[0] = &handle; inparam[1] = &msgsize; outparam[0] = addr; outparam[1] = &msgsize; if (__modplc_sendcmd__(hd, '4', "ss", inparam, NULL, msg)) return msgsize; return 0; } /* Funcin modplc_dlpoll: Verifica la llegada de un nuevo mensaje por medio de la capa de enlace del modem PLC. */ int modplc_dlpoll(modplc_hd *hd, int handle) { /* Variables. */ unsigned char result; void *inparam[1]; void *outparam[1];

"as", outparam,

/* Resultado del comando. */ /* Parmetros de entrada del comando. */ /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0; /* Verifica la llegada de un nuevo mensaje. */ inparam[0] = &handle; outparam[0] = &result; if (__modplc_sendcmd__(hd, '5', "s", inparam, NULL, NULL)) return (result == 1); return 0; } /* Funcin modplc_dlgetaddress:

"b", outparam,

524

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Devuelve la direccin fsica de la capa de enlace del modem PLC. */ int modplc_dlgetaddress(modplc_hd *hd, unsigned char iface, modplc_dlphyaddr paddr) { /* Variables. */ void *inparam[1]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0; /* Devuelve la direccin fsica. */ inparam[0] = &iface; outparam[0] = paddr; return __modplc_sendcmd__(hd, '6', "b", inparam, NULL, NULL); } /* Funcin modplc_dladdlogaddress: Agrega una nueva direccin lgica a la capa de enlace del modem PLC. */ int modplc_dladdlogaddress(modplc_hd *hd, unsigned char iface, unsigned char prot, modplc_dllogaddr laddr) { /* Variables. */ unsigned char result; /* Resultado del comando. */ void *inparam[3]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

"a", outparam,

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0; /* Agrega una nueva direccin lgica. */ inparam[0] = &iface; inparam[1] = &prot; inparam[2] = &laddr; outparam[0] = &result; if (__modplc_sendcmd__(hd, '7', "bbl", inparam, NULL, NULL)) return (result == 1); return 0; } /* Funcin modplc_dldellogaddress: Elimina una direccin lgica a la capa de enlace del modem PLC. */ int modplc_dldellogaddress(modplc_hd *hd, unsigned char iface, unsigned char prot, modplc_dllogaddr laddr) { /* Variables. */ unsigned char result; /* Resultado del comando. */ void *inparam[3]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

"b", outparam,

FernandoArielBeunza79156

525

Tesis de Grado en Ingeniera Informtica


/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0; /* Elimina una direccin lgica. */ inparam[0] = &iface; inparam[1] = &prot; inparam[2] = &laddr; outparam[0] = &result; if (__modplc_sendcmd__(hd, '8', "bbl", inparam, NULL, NULL)) return (result == 1); return 0; } /* Funcin modplc_dlgetphyaddress: Devuelve la direccin fsica asociada a la direccin lgica de la capa de enlace del modem PLC. */ int modplc_dlgetphyaddress(modplc_hd *hd, unsigned char iface, unsigned char prot, modplc_dllogaddr laddr, modplc_dlphyaddr paddr) { /* Variables. */ void *inparam[3]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

"b", outparam,

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0; /* Devuelve la direccin fsica asociada a la direccin lgica. */ inparam[0] = &iface; inparam[1] = &prot; inparam[2] = &laddr; outparam[0] = paddr; return __modplc_sendcmd__(hd, '9', "bbl", inparam, NULL, "a", outparam, NULL); } /* Funcin modplc_dlgetpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de enlace del modem PLC. */ size_t modplc_dlgetpayloadsize(modplc_hd *hd, unsigned char iface) { /* Variables. */ unsigned short int payloadsize; /* Cantidad mxima de bytes que puede contener una trama. */ void *inparam[1]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de enlace. */ if (hd->layer != MODPLC_DATALINKLAYER) return 0;

526

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Devuelve la cantidad mxima de byes que puede contener un mensaje. */ inparam[0] = &iface; outparam[0] = &payloadsize; if (__modplc_sendcmd__(hd, 'a', "b", inparam, NULL, "s", outparam, NULL)) return (size_t) payloadsize; return 0; } /* Funcin modplc_sppublish: Registra el dispositivo como publicador del grupo de difusin especificado de la capa de sesin del modem PLC. */ int modplc_sppublish(modplc_hd *hd, modplc_spgrpid grpid) { /* Variables. */ unsigned char result; void *inparam[1]; void *outparam[1];

/* Resultado del comando. */ /* Parmetros de entrada del comando. */ /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de sesin. */ if (hd->layer != MODPLC_SESSIONLAYER) return 0; /* Registra el dispositivo como publicador del grupo de difusin especificado. */ inparam[0] = &grpid; outparam[0] = &result; if (__modplc_sendcmd__(hd, '1', "b", inparam, NULL, "b", outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_spsubscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado de la capa de sesin del modem PLC. */ int modplc_spsubscribe(modplc_hd *hd, modplc_spgrpid grpid) { /* Variables. */ unsigned char result; /* Resultado del comando. */ void *inparam[1]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de sesin. */ if (hd->layer != MODPLC_SESSIONLAYER) return 0; /* Registra el dispositivo como suscriptor del grupo de difusin especificado. */ inparam[0] = &grpid; outparam[0] = &result; if (__modplc_sendcmd__(hd, '2', "b", inparam, NULL, "b", outparam, NULL)) return (result == 1); return 0; }

FernandoArielBeunza79156

527

Tesis de Grado en Ingeniera Informtica


/* Funcin modplc_spleave: Desvincula el dispositivo del grupo de difusin especificado de la capa de sesin del modem PLC. */ int modplc_spleave(modplc_hd *hd, modplc_spgrpid grpid) { /* Variables. */ unsigned char result; void *inparam[1]; void *outparam[1];

/* Resultado del comando. */ /* Parmetros de entrada del comando. */ /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de sesin. */ if (hd->layer != MODPLC_SESSIONLAYER) return 0; /* Desvincula el dispositivo del grupo de difusin especificado. */ inparam[0] = &grpid; outparam[0] = &result; if (__modplc_sendcmd__(hd, '3', "b", inparam, NULL, "b", outparam, NULL)) return (result == 1); return 0; } /* Funcin modplc_spsend: Enva un mensaje por medio de la capa de sesin del modem PLC. */ size_t modplc_spsend(modplc_hd *hd, modplc_spgrpid grpid, int nosec, const void *msg, size_t msgsize) { /* Variables. */ void *inparam[3]; /* Parmetros de entrada del comando. */ void *outparam[1]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de sesin. */ if (hd->layer != MODPLC_SESSIONLAYER) return 0; /* Enva un mensaje. */ inparam[0] = &grpid; inparam[1] = &nosec; inparam[2] = &msgsize; outparam[0] = &msgsize; if (__modplc_sendcmd__(hd, '4', "bbs", inparam, msg, NULL)) return msgsize; return 0; } /* Funcin modplc_spreceive: Recibe un mensaje por medio de la capa de sesin del modem PLC. */ size_t modplc_spreceive(modplc_hd *hd, modplc_spgrpid *grpid, void *msg, size_t msgsize) { /* Variables. */ void *inparam[1]; /* Parmetros de entrada del comando. */

"s", outparam,

528

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


void *outparam[2]; /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de sesin. */ if (hd->layer != MODPLC_SESSIONLAYER) return 0; /* Recibe un mensaje. */ inparam[0] = &msgsize; outparam[0] = grpid; outparam[1] = &msgsize; if (__modplc_sendcmd__(hd, '5', "s", inparam, NULL, msg)) return msgsize; return 0; } /* Funcin modplc_sppoll: Verifica la llegada de un nuevo mensaje por medio de la capa de sesin del modem PLC. */ int modplc_sppoll(modplc_hd *hd) { /* Variables. */ unsigned char result; void *outparam[1];

"bs", outparam,

/* Resultado del comando. */ /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de sesin. */ if (hd->layer != MODPLC_SESSIONLAYER) return 0; /* Verifica la llegada de un nuevo mensaje. */ outparam[0] = &result; if (__modplc_sendcmd__(hd, '6', "", NULL, NULL, return (result == 1); return 0; } /* Funcin modplc_spgetpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de sesin del modem PLC. */ size_t modplc_spgetpayloadsize(modplc_hd *hd) { /* Variables. */ unsigned short int payloadsize; void *outparam[1];

"b", outparam, NULL))

/* Cantidad mxima de bytes que puede contener una trama. */ /* Parmetros de salida del comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Verifica que la capa a la que se accede es la capa de sesin. */ if (hd->layer != MODPLC_SESSIONLAYER) return 0; /* Devuelve la cantidad mxima de byes que puede contener un mensaje. */ outparam[0] = &payloadsize; if (__modplc_sendcmd__(hd, '7', "", NULL, NULL, "s", outparam, NULL)) return (size_t) payloadsize;

FernandoArielBeunza79156

529

Tesis de Grado en Ingeniera Informtica


return 0; }

/* Implementacin de funciones privadas. */ /* Funcin __modplc_sendcmdline__: Enva una lnea de comando por medio de la interfaz de comunicacin por puerto serie. */ static char __modplc_sendcmdline__(modplc_hd *hd, const char *cmdline, char *resp, size_t respsize) { /* Variables. */ size_t send; /* Cantidad de bytes por envo. */ size_t size; /* Tamaoo de la lnea de respuesta. */ char *lastchar; /* Puntero al ltimo caracter. */ char respline[MODPLC_BUFFERSIZE]; /* Respuesta a la lnea de comando. */

/* Verifica que el manejador de interfaz con el modem PLC exista. */ if (!hd) return 0; /* Recibe la respuesta al comando. */ size = 0; *respline = 0; while(size < respsize) { /* Enva un fragmento de la lnea de comando. */ send = strlen(cmdline) - size; if (send > MODPLC_FRAGMENTLINESIZE) send = MODPLC_FRAGMENTLINESIZE; if (size < strlen(cmdline)) serial_send(hd->serialhd, cmdline + size, send); /* Recibe la respuesta. */ size += serial_receive(hd->serialhd, respline + size, respsize - size); *(respline + size) = 0; /* Verifica si se recibi el smbolo de la lnea de comando. */ lastchar = strchr(respline, '#'); if (lastchar) break; lastchar = strchr(respline, '?'); if (lastchar) break; lastchar = strchr(respline, '$'); if (lastchar) break; lastchar = strchr(respline, '>'); if (lastchar) break; if (size > respsize) { lastchar = respline + size - 1; break; } } /* Devuelve la respuesta al comando. */ if (resp) strcpy(resp, respline); if (hd->debugmode && size) { printf("%s", respline); fflush(stdout); } return *lastchar; } /* Funcin __modplc_sendcmd__: Enva un comando por medio de la interfaz de comunicacin por puerto

530

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


serie y devuelve su respuesta. */ static int __modplc_sendcmd__(modplc_hd *hd, char op, const char *infmt, void **inparam, const void *inframe, const char *outfmt, void **outparam, void *outframe) { /* Variables. */ int param; /* Nmero de parmetro. */ size_t i; /* Contador. */ size_t j; /* Contador. */ size_t framesize; /* Tamao de la trama. */ unsigned char *ptrline; /* Puntero a la lnea de respuesta de comando. */ unsigned char *ptrparam; /* Puntero al parmetro. */ unsigned char *ptrresp; /* Puntero a la respuesta. */ unsigned char *ptrframe; /* Puntero a la trama. */ unsigned int dat1; /* Dato. */ unsigned char dat2; /* Dato. */ char hexval[3]; /* Valor hexadecimal. */ char cmdline[MODPLC_BUFFERSIZE]; /* Lnea de comando. */ char rline[MODPLC_BUFFERSIZE]; /* Lnea de respuesta de comando. */ char respline[MODPLC_BUFFERSIZE]; /* Lnea de respuesta de comando. */

/* Verifica que el modem PLC se encuentre en estado activo. */ modplc_status(hd); if (!hd->status) return 0; /* Enva el comando y sus parmetros. */ param = 0; *(cmdline + 0) = op; *(cmdline + 1) = '\n'; *(cmdline + 2) = 0; while(infmt && inparam) { /* Enva el comando y un parmetro procesado. */ if (!infmt[param]) break; if (__modplc_sendcmdline__(hd, cmdline, cmdline, MODPLC_BUFFERSIZE) != '>') return 0; /* Procesa el siguiente parmetro a enviar. */ ptrparam = (unsigned char *) inparam[param]; if (infmt[param] == 'b') sprintf(cmdline, "\\%02X\n", *((unsigned char *) inparam[param])); else if (infmt[param] == 's') sprintf(cmdline, "\\%02X\\%02X\n", ptrparam[1], ptrparam[0]); else if (infmt[param] == 'l') sprintf(cmdline, "\\%02X\\%02X\\%02X\\%02X\n", ptrparam[3], ptrparam[2], ptrparam[1], ptrparam[0]); else if (infmt[param] == 'a') sprintf(cmdline, "\\%02X\\%02X\\%02X\\%02X\\%02X\\%02X\\%02X\\%02X\n", ptrparam[0], ptrparam[1], ptrparam[2], ptrparam[3], ptrparam[4], ptrparam[5], ptrparam[6], ptrparam[7]); param ++; } /* Si hay una trama que enviar se enva su contenido. */ if (inframe) { /* Espera para poder enviar la trama. */ if (__modplc_sendcmdline__(hd, cmdline, respline, MODPLC_BUFFERSIZE) != '>') return 0;

FernandoArielBeunza79156

531

Tesis de Grado en Ingeniera Informtica


/* Enva la trama. */ *cmdline = 0; ptrframe = (unsigned char *) inframe; framesize = *((size_t *) inparam[param - 1]); for(i = 0; i < framesize; ) { dat2 = (unsigned char) *ptrframe; if ((dat2 >= 0x20) && (dat2 <= 0x7e) && (dat2 != '\\') && (dat2 != '#') && (dat2 != '?') && (dat2 != '$') && (dat2 != '>')) sprintf(hexval, "%c", dat2); else sprintf(hexval, "\\%02X", dat2); strcat(cmdline, hexval); ptrframe ++; i ++; if ((i & 0x000f) && (i < framesize)) continue; strcat(cmdline, "\n"); if (__modplc_sendcmdline__(hd, cmdline, respline, MODPLC_BUFFERSIZE) != '>') break; *cmdline = 0; } } /* Caso contrario se espera la respuesta al comando. */ else { if (__modplc_sendcmdline__(hd, cmdline, respline, MODPLC_BUFFERSIZE) != '$') return 0; } /* Recibe los parmetros de respuesta. */ i = 0; param = 0; ptrresp = (unsigned char *) respline; while(*ptrresp != '$') { if (*ptrresp == '\r') { ptrresp ++; continue; } else if (*ptrresp != '\n') { rline[i++] = *(ptrresp ++); continue; } rline[i] = 0; ptrresp ++; i = 0; if (!strlen(rline)) continue; if (param < 1) { param ++; continue; } if (!outfmt[param - 1]) { ptrresp -= (strlen(rline) + 2); break; } ptrline = (unsigned char *) rline; ptrparam = (unsigned char *) outparam[param - 1]; if (outfmt[param - 1] == 'b') { if (*ptrline != '\\')

532

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


*ptrparam = *(ptrline ++); else { ptrline ++; hexval[0] = *(ptrline ++); hexval[1] = *(ptrline ++); hexval[2] = 0; sscanf(hexval, "%X", &dat1); *ptrparam = (unsigned char) dat1; } } else if (outfmt[param - 1] == 's') { for(j = 0; j < 2; j++) { if (*ptrline != '\\') *(ptrparam + 1 - j) = *(ptrline ++); else { ptrline ++; hexval[0] = *(ptrline ++); hexval[1] = *(ptrline ++); hexval[2] = 0; sscanf(hexval, "%X", &dat1); *(ptrparam + 1 - j) = (unsigned char) dat1; } } } else if (outfmt[param - 1] == 'l') { for(j = 0; j < 4; j++) { if (*ptrline != '\\') *(ptrparam + 3 - j) = *(ptrline ++); else { ptrline ++; hexval[0] = *(ptrline ++); hexval[1] = *(ptrline ++); hexval[2] = 0; sscanf(hexval, "%X", &dat1); *(ptrparam + 3 - j) = (unsigned char) dat1; } } } else if (outfmt[param - 1] == 'a') { for(j = 0; j < 8; j++) { if (*ptrline != '\\') *(ptrparam + j) = *(ptrline ++); else { ptrline ++; hexval[0] = *(ptrline ++); hexval[1] = *(ptrline ++); hexval[2] = 0; sscanf(hexval, "%X", &dat1); *(ptrparam + j) = (unsigned char) dat1; } } } param++; } /* Si hay una trama que recibir se recibe su contenido. */ if (outframe) { ptrframe = (unsigned char *) outframe;

FernandoArielBeunza79156

533

Tesis de Grado en Ingeniera Informtica


framesize = *((size_t *) outparam[param - 2]); for(j = 0; j < framesize; ) { dat2 = *(ptrresp ++); if ((dat2 == '\n') || (dat2 == '\r')) continue; if (dat2 != '\\') *ptrframe = dat2; else { hexval[0] = *(ptrresp ++); hexval[1] = *(ptrresp ++); hexval[2] = 0; sscanf(hexval, "%X", &dat1); *ptrframe = (unsigned char) dat1; } ptrframe ++; j ++; } } /* xito. */ return 1; }

C.4.4.6. Archivo modsp.h


/* modsp.h: Declaracin de funciones referentes a la interfaz de la capa de sesin del modem PLC. */

#if !defined(__MODSP_H__) #define __MODSP_H__

/* Archivos includos necesarios. */ #include "config.h" #include <pthread.h> #include "modplc.h"

/* Definicin de tipos. */ /* Identificador de grupo. */ typedef unsigned char modsp_grpid; /* Manejador de interfaz con la capa de sesin del modem PLC. */ typedef struct { pthread_mutex_t mutexsem; /* Semforo de exclusin mtua. */ pthread_t detectthread; /* Manejador de hilo de deteccin de recepcin. */ size_t payloadsize; /* Cantidad mxima de bytes que puede contener un mensaje. */ modplc_hd *modplchd; /* Manejador de interfaz con el modem PLC. */ void (*recfun) (void *, modsp_grpid, void *, size_t, void *); /* Funcin manejadora de mensajes recibidos. */ void *param; /* Parmetros para la funcin manejadora de mensajes recibidos. */ } modsp_hd;

534

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Declaracin de funciones pblicas. */ /* Funcin modsp_init: Inicializa los recursos utilizados por la capa de sesin del modem PLC. */ modsp_hd *modsp_init(int, int); /* Funcin modsp_release: Libera los recursos utilizados por la capa de sesin del modem PLC. */ int modsp_release(modsp_hd *); /* Funcin modsp_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ int modsp_publish(modsp_hd *, modsp_grpid); /* Funcin modsp_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ int modsp_subscribe(modsp_hd *, modsp_grpid); /* Funcin modsp_leave: Desvincula el dispositivo del grupo de difusin especificado. */ int modsp_leave(modsp_hd *, modsp_grpid); /* Funcin modsp_send: Enva un mensaje por medio de la capa de sesin del modem PLC. */ size_t modsp_send(modsp_hd *, modsp_grpid, unsigned char, const void *, size_t); /* Funcin modsp_receive: Recibe un mensaje por medio de la capa de sesin del modem PLC. */ size_t modsp_receive(modsp_hd *, modsp_grpid *, void *, size_t); /* Funcin modsp_notify: Define una funcin manejadora de mensajes recibidos. */ int modsp_notify(modsp_hd *, void (*func)(modsp_hd *, modsp_grpid, void *, size_t, void *), void *); /* Funcin modsp_poll: Verifica la llegada de un nuevo mensaje. */ int modsp_poll(modsp_hd *); /* Funcin modsp_status: Devuelve el estado del modem PLC. */ int modsp_status(modsp_hd *); /* Funcin modsp_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de sesin del modem PLC.

FernandoArielBeunza79156

535

Tesis de Grado en Ingeniera Informtica


*/ size_t modsp_getpayloadsize(modsp_hd *);

#endif

C.4.4.7. Archivo modsp.c


/* modsp.c: Implementacin de funciones referentes a la interfaz de la capa de sesin del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <pthread.h> #include "modplc.h" #include "modsp.h"

/* Declaracin de funciones privadas. */ static void *__modsp_detectproc__(void *);

/* Implementacin de funciones pblicas. */ /* Funcin modsp_init: Inicializa los recursos utilizados por la capa de sesin del modem PLC. */ modsp_hd *modsp_init(int sid, int debugmode) { /* Variables. */ modsp_hd *handle;

/* Manejador de interfaz con la capa de sesin del modem PLC. */

/* Crea un nuevo manejador de interfaz con la capa de sesin del modem PLC. */ handle = (modsp_hd *) malloc(sizeof(modsp_hd)); if (!handle) return NULL; /* Inicializa el manejador de interfaz con la capa de sesin del modem PLC. */ while(1) { /* Inicializa el manejador de interfaz con el modem PLC. */ handle->modplchd = modplc_init(sid, MODPLC_SESSIONLAYER, debugmode); if (!handle->modplchd) break; /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ handle->payloadsize = modplc_spgetpayloadsize(handle->modplchd); if (!handle->payloadsize) break; /* Inicializa el manejador de mensajes recibidos. */ handle->param = NULL; handle->recfun = NULL; /* Inicializa semforo. */ if (pthread_mutex_init(&(handle->mutexsem), NULL)) break; if (pthread_mutex_unlock(&(handle->mutexsem))) break; /* Devuelve el manejador creado. */

536

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


return handle; } /* No se pudo inicializar la interfaz con la capa de sesin del modem PLC. */ pthread_mutex_destroy(&(handle->mutexsem)); modplc_release(handle->modplchd); free(handle); return NULL; } /* Funcin modsp_release: Libera los recursos utilizados por la capa de sesin del modem PLC. */ int modsp_release(modsp_hd *hd) { /* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Libera el manejador de mensajes recibidos. */ modsp_notify(hd, NULL, NULL); /* Libera los recursos utilizados por el semforo de exclusin mtua. */ if (pthread_mutex_destroy(&(hd->mutexsem))) return 0; /* Libera la interfaz con el modem PLC. */ modplc_release(hd->modplchd); /* Libera los recursos utilizados por la interfaz con la capa de sesin del modem PLC. */ free(hd); /* xito. */ return 1; } /* Funcin modsp_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ int modsp_publish(modsp_hd *hd, modsp_grpid grpid) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Registra el dispositivo como publicador. */ result = modplc_sppublish(hd->modplchd, grpid); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve el resultado del registro del dispositivo. */ return result; } /* Funcin modsp_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado.

FernandoArielBeunza79156

537

Tesis de Grado en Ingeniera Informtica


*/ int modsp_subscribe(modsp_hd *hd, modsp_grpid grpid) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Registra el dispositivo como suscriptor. */ result = modplc_spsubscribe(hd->modplchd, grpid); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve el resultado del registro del dispositivo. */ return result; } /* Funcin modsp_leave: Desvincula el dispositivo del grupo de difusin especificado. */ int modsp_leave(modsp_hd *hd, modsp_grpid grpid) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Desvincula el dispositivo. */ result = modplc_spleave(hd->modplchd, grpid); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve el resultado de la desvinculacin del dispositivo. */ return result; } /* Funcin modsp_send: Enva un mensaje por medio de la capa de sesin del modem PLC. */ size_t modsp_send(modsp_hd *hd, modsp_grpid grpid, unsigned char nosec, const void *msg, size_t msgsize) { /* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Enva un mensaje. */ msgsize = modplc_spsend(hd->modplchd, grpid, nosec, msg, msgsize);

538

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve la cantidad de bytes envados. */ return msgsize; } /* Funcin modsp_receive: Recibe un mensaje por medio de la capa de sesin del modem PLC. */ size_t modsp_receive(modsp_hd *hd, modsp_grpid *grpid, void *msg, size_t msgsize) { /* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera la llegada de un mensaje. */ while(!modsp_poll(hd)); /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Recibe un mensaje. */ msgsize = modplc_spreceive(hd->modplchd, grpid, msg, msgsize); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve la cantidad de bytes recibidos. */ return msgsize; } /* Funcin modsp_notify: Define una funcin manejadora de mensajes recibidos. */ int modsp_notify(modsp_hd *hd, void (*func)(modsp_hd *, modsp_grpid, void *, size_t, void *), void *param) { /* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Si la funcin manejadora es nula y no hay ninguna funcin manejadora definida previamente no se hace nada. */ if ((!func) && (!hd->recfun)) return 1; /* Si la funcin manejadora no es nula y hay una funcin manejadora previamente definida actualiza la funcin manejadora. */ if ((func) && (hd->recfun)) { if (pthread_mutex_lock(&(hd->mutexsem))) return 0; hd->recfun = (void (*)(void *, modsp_grpid, void *, size_t, void *)) func; hd->param = param; if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; return 1; } /* Si la funcin manejadora es nula y hay una funcin manejadora definida previamente se elimina esta ltima. */ if ((!func) && (hd->recfun)) { if (pthread_mutex_lock(&(hd->mutexsem))) return 0; hd->recfun = NULL; hd->param = param; if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; if (pthread_join(hd->detectthread, NULL)) return 0;

FernandoArielBeunza79156

539

Tesis de Grado en Ingeniera Informtica


return 1; } /* Si la funcin manejadora no es nula y no hay una funcin manejadora previamente definida se define la nueva funcin manejadora. */ if ((func) && (!hd->recfun)) { if (pthread_mutex_lock(&(hd->mutexsem))) return 0; hd->recfun = (void (*)(void *, modsp_grpid, void *, size_t, void *)) func; hd->param = param; if (pthread_create(&(hd->detectthread), NULL, __modsp_detectproc__, hd)) { hd->recfun = NULL; hd->param = NULL; pthread_mutex_unlock(&(hd->mutexsem)); return 0; } if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; return 1; } /* No se pudo definir la funcin manejadora de mensajes recibidos. */ return 0; } /* Funcin modsp_poll: Verifica la llegada de un nuevo mensaje. */ int modsp_poll(modsp_hd *hd) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Verifica la recepcin de un mensaje. */ result = modplc_sppoll(hd->modplchd); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve el resultado de la verificacin de la recepcin de un mensaje. */ return result; } /* Funcin modsp_status: Devuelve el estado del modem PLC. */ int modsp_status(modsp_hd *hd) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem

540

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Obtiene el estado del modem PLC. */ result = modplc_status(hd->modplchd); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve el resultado del modem PLC. */ return result; } /* Funcin modsp_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de sesin del modem PLC. */ size_t modsp_getpayloadsize(modsp_hd *hd) { /* Variables. */ size_t payloadsize;

/* Cantidad mxima de bytes que puede contener un mensaje. */

/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ payloadsize = modplc_spgetpayloadsize(hd->modplchd); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve la cantidad mxima de bytes que puede contener un mensaje. */ return payloadsize; }

/* Implementacin de funciones privadas. */ /* Funcin __modsp_detectproc__: Verifica la existencia de un mensaje recibido disponible para ser ledo. */ static void *__modsp_detectproc__(void *param) { /* Variables. */ int recvflag; size_t msgsize; modsp_grpid grpid; modsp_hd *hd; void (*func) (void *, modsp_grpid, void *, size_t, void *); unsigned char *msg;

/* Indicador de recepcin de un mensaje. */ /* Tamaoo del mensaje recibido. */ /* Identificador de grupo. */ /* Manejador de interfaz con la capa de sesin del modem PLC. */

/* Manejador de mensajes recibidos. */ /* Puntero al mensaje recibido. */

/* Carga el manejador de interfaz con la capa de sesin del modem PLC. */

FernandoArielBeunza79156

541

Tesis de Grado en Ingeniera Informtica


hd = (modsp_hd *) param; /* Verifica la existencia de un mensaje recibido. */ while(1) { /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) continue; /* Verifica la recepcin de un mensaje. */ func = hd->recfun; if (!func) break; recvflag = modplc_sppoll(hd->modplchd); if (recvflag) { msg = (unsigned char *) malloc(hd->payloadsize * sizeof(unsigned char)); if (msg) msgsize = modplc_spreceive(hd->modplchd, &grpid, msg, hd->payloadsize); else recvflag = 0; } /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ pthread_mutex_unlock(&(hd->mutexsem)); /* Verifica si se ha detectado la recepcin de un mensaje para invocar a la funcin manejadora de mensajes recibidos. */ if (recvflag) { func(hd, grpid, msg, msgsize, hd->param); free(msg); } } /* Fin de ejecucin del hilo de deteccin de recepcin. */ pthread_mutex_unlock(&(hd->mutexsem)); pthread_exit(0); }

C.4.4.8. Archivo moddl.h


/* moddl.h: Declaracin de funciones referentes a la interfaz de la capa de enlace del modem PLC. */

#if !defined(__MODDL_H__) #define __MODDL_H__

/* Archivos includos necesarios. */ #include "config.h" #include <pthread.h> #include "modplc.h"

/* Definicin de tipos. */ /* Direccin fsica del modem PLC. */ typedef unsigned char moddl_phyaddr[8]; /* Direccin lgica del modem PLC. */

542

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


typedef unsigned long int moddl_logaddr; /* Manejador de interfaz con la capa de enlace del modem PLC. */ typedef struct { pthread_mutex_t mutexsem; /* Semforo de exclusin mtua. */ unsigned long int conncounter; /* Contador de conexiones abiertas. */ modplc_hd *modplchd; /* Manejador de interfaz con el modem PLC. */ } moddl_hd; /* Manejador de conexin por medio de la capa de enlace del modem PLC. */ typedef struct { pthread_t detectthread; /* Manejador de hilo de deteccin de recepcin. */ int handle; /* Identificador de conexin. */ size_t payloadsize; /* Cantidad mxima de bytes que puede contener un mensaje. */ unsigned char iface; /* Identificador de intarfaz fsica. */ moddl_hd *moddlhd; /* Manejador de interfaz con la capa de enlance del modem PLC. */ void (*recfun) (void *, moddl_phyaddr, void *, size_t, void *); /* Funcin manejadora de mensajes recibidos. */ void *param; /* Parmetros para la funcin manejadora de mensajes recibidos. */ } moddlconn_hd;

/* Declaracin de funciones pblicas. */ /* Funcin moddl_init: Inicializa los recursos utilizados por la capa de enlace del modem PLC. */ moddl_hd *moddl_init(int, int); /* Funcin moddl_release: Libera los recursos utilizados por la capa de enlace del modem PLC. */ int moddl_release(moddl_hd *); /* Funcin moddl_open: Abre una conexin por medio de la capa de enlace del modem PLC. */ moddlconn_hd *moddl_open(moddl_hd *, unsigned char, unsigned char); /* Funcin moddl_close: Cierra una conexin por medio de la capa de enlace del modem PLC. */ int moddl_close(moddlconn_hd *); /* Funcin moddl_send: Enva un mensaje por medio de la capa de enlace del modem PLC. */ size_t moddl_send(moddlconn_hd *, moddl_phyaddr, unsigned char, const void *, size_t); /* Funcin moddl_receive: Recibe un mensaje por medio de la capa de enlace del modem PLC.

FernandoArielBeunza79156

543

Tesis de Grado en Ingeniera Informtica


*/ size_t moddl_receive(moddlconn_hd *, moddl_phyaddr, void *, size_t); /* Funcin moddl_notify: Define una funcin manejadora de mensajes recibidos. */ int moddl_notify(moddlconn_hd *, void (*func)(moddlconn_hd *, moddl_phyaddr, void *, size_t, void *), void *); /* Funcin modsp_poll: Verifica la llegada de un nuevo mensaje. */ int moddl_poll(moddlconn_hd *); /* Funcin moddl_getaddress: Devuelve la direccin fsica de la capa de enlace del modem PLC. */ int moddl_getaddress(moddl_hd *, unsigned char, moddl_phyaddr); /* Funcin moddl_addlogaddress: Agrega una nueva direccin lgica a la capa de enlade del modem PLC. */ int moddl_addlogaddress(moddl_hd *, unsigned char, unsigned char, moddl_logaddr); /* Funcin moddl_dellogaddress: Elimina una direccin lgica a la capa de enlace del modem PLC. */ int moddl_dellogaddress(moddl_hd *, unsigned char, unsigned char, moddl_logaddr); /* Funcin moddl_getphyaddress: Devuelve la direccin fsica asociada a la direccin lgica de la capa de enlace del modem PLC. */ int moddl_getphyaddress(moddl_hd *, unsigned char, unsigned char, moddl_logaddr, moddl_phyaddr); /* Funcin moddl_status: Devuelve el estado del modem PLC. */ int moddl_status(moddl_hd *); /* Funcin moddl_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de enlace del modem PLC. */ size_t moddl_getpayloadsize(moddl_hd *, unsigned char);

#endif

C.4.4.9. Archivo moddl.c


/* moddl.c: Implementacin de funciones referentes a la interfaz de la capa de enlace del modem PLC. */

544

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Archivos includos necesarios. */ #include "config.h" #include <pthread.h> #include "modplc.h" #include "moddl.h"

/* Declaracin de funciones privadas. */ static void *__moddl_detectproc__(void *);

/* Implementacin de funciones pblicas. */ /* Funcin moddl_init: Inicializa los recursos utilizados por la capa de enlace del modem PLC. */ moddl_hd *moddl_init(int sid, int debugmode) { /* Variables. */ moddl_hd *handle;

/* Manejador de interfaz con la capa de enlace del modem PLC. */

/* Crea un nuevo manejador de interfaz con la capa de enlace del modem PLC. */ handle = (moddl_hd *) malloc(sizeof(moddl_hd)); if (!handle) return NULL; /* Inicializa el manejador de interfaz con la capa de enlace del modem PLC. */ while(1) { /* Inicializa el manejador de interfaz con el modem PLC. */ handle->modplchd = modplc_init(sid, MODPLC_DATALINKLAYER, debugmode); if (!handle->modplchd) break; /* Inicializa el contador de conexiones abiertas. */ handle->conncounter = 0; /* Inicializa semforo. */ if (pthread_mutex_init(&(handle->mutexsem), NULL)) break; if (pthread_mutex_unlock(&(handle->mutexsem))) break; /* Devuelve el manejador creado. */ return handle; } /* No se pudo inicializar la interfaz con la capa de enlace del modem PLC. */ pthread_mutex_destroy(&(handle->mutexsem)); modplc_release(handle->modplchd); free(handle); return NULL; } /* Funcin moddl_release: Libera los recursos utilizados por la capa de enlace del modem PLC. */ int moddl_release(moddl_hd *hd) { /* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Verifica que no existan conexiones abiertas. */ if (hd->conncounter) return 0;

FernandoArielBeunza79156

545

Tesis de Grado en Ingeniera Informtica


/* Libera los recursos utilizados por el semforo de exclusin mtua. */ if (pthread_mutex_destroy(&(hd->mutexsem))) return 0; /* Libera la interfaz con el modem PLC. */ modplc_release(hd->modplchd); /* Libera los recursos utilizados por la interfaz con la capa de enlace del modem PLC. */ free(hd); /* xito. */ return 1; } /* Funcin moddl_open: Abre una conexin por medio de la capa de enlace del modem PLC. */ moddlconn_hd *moddl_open(moddl_hd *hd, unsigned char iface, unsigned char prot) { /* Variables. */ moddlconn_hd *handle; /* Manejador de conexin de la capa de enlace del modem PLC. */

/* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return NULL; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return NULL; /* Crea un nuevo manejador de conexin por medio de la capa de enlace del modem PLC. */ handle = (moddlconn_hd *) malloc(sizeof(moddlconn_hd)); if (!handle) { pthread_mutex_unlock(&(hd->mutexsem)); return NULL; } /* Inicializa el manejador de conexin. */ while(1) { /* Abre una conexin. */ handle->moddlhd = hd; handle->iface = iface; handle->handle = modplc_dlopen(hd->modplchd, handle->iface, prot); if (!handle->handle) break; /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ handle->payloadsize = modplc_dlgetpayloadsize(hd->modplchd, iface); if (!handle->payloadsize) break; /* Inicializa el manejador de mensajes recibidos. */ handle->param = NULL; handle->recfun = NULL; /* Actualiza el nmero de conexiones. */ handle->moddlhd->conncounter ++; /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) break; /* Devuelve el manejador creado. */ return handle;

546

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


} /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ pthread_mutex_unlock(&(hd->mutexsem)); /* No se pudo abrir la conexin. */ modplc_dlclose(hd->modplchd, handle->handle); free(handle); return NULL; } /* Funcin moddl_close: Cierra una conexin por medio de la capa de enlace del modem PLC. */ int moddl_close(moddlconn_hd *hd) { /* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Libera el manejador de mensajes recibidos. */ moddl_notify(hd, NULL, NULL); /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->moddlhd->mutexsem))) return 0; /* Actualiza el nmero de conexiones. */ hd->moddlhd->conncounter --; /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->moddlhd->mutexsem))) return 0; /* Libera los recursos utilizados por la conexin por medio de la capa de enlace del modem PLC. */ free(hd); /* xito. */ return 1; } /* Funcin moddl_send: Enva un mensaje por medio de la capa de enlace del modem PLC. */ size_t moddl_send(moddlconn_hd *hd, moddl_phyaddr addr, unsigned char prio, const void *msg, size_t msgsize) { /* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->moddlhd->mutexsem))) return 0; /* Enva un mensaje. */ msgsize = modplc_dlsend(hd->moddlhd->modplchd, hd->handle, addr, prio, msg, msgsize); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->moddlhd->mutexsem))) return 0; /* Devuelve la cantidad de bytes recibidos. */ return msgsize; } /* Funcin moddl_receive: Recibe un mensaje por medio de la capa de enlace del modem PLC.

FernandoArielBeunza79156

547

Tesis de Grado en Ingeniera Informtica


*/ size_t moddl_receive(moddlconn_hd *hd, moddl_phyaddr addr, void *msg, size_t msgsize) { /* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera la llegada de un mensaje. */ while(!moddl_poll(hd)); /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->moddlhd->mutexsem))) return 0; /* Recibe un mensaje. */ msgsize = modplc_dlreceive(hd->moddlhd->modplchd, hd->handle, addr, msg, msgsize); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->moddlhd->mutexsem))) return 0; /* Devuelve la cantidad de bytes recibidos. */ return msgsize; } /* Funcin moddl_notify: Define una funcin manejadora de mensajes recibidos. */ int moddl_notify(moddlconn_hd *hd, void (*func)(moddlconn_hd *, moddl_phyaddr, void *, size_t, void *), void *param) { /* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Si la funcin manejadora es nula y no hay ninguna funcin manejadora definida previamente no se hace nada. */ if ((!func) && (!hd->recfun)) return 1; /* Si la funcin manejadora no es nula y hay una funcin manejadora previamente definida actualiza la funcin manejadora. */ if ((func) && (hd->recfun)) { if (pthread_mutex_lock(&(hd->moddlhd->mutexsem))) return 0; hd->recfun = (void (*)(void *, moddl_phyaddr, void *, size_t, void *)) func; hd->param = param; if (pthread_mutex_unlock(&(hd->moddlhd->mutexsem))) return 0; return 1; } /* Si la funcin manejadora es nula y hay una funcin manejadora definida previamente se elimina esta ltima. */ if ((!func) && (hd->recfun)) { if (pthread_mutex_lock(&(hd->moddlhd->mutexsem))) return 0; hd->recfun = NULL; hd->param = param; if (pthread_mutex_unlock(&(hd->moddlhd->mutexsem))) return 0; if (pthread_join(hd->detectthread, NULL)) return 0; return 1; } /* Si la funcin manejadora no es nula y no hay una funcin manejadora previamente definida se define la nueva funcin manejadora. */ if ((func) && (!hd->recfun)) { if (pthread_mutex_lock(&(hd->moddlhd->mutexsem))) return 0; hd->recfun = (void (*)(void *, moddl_phyaddr, void *, size_t,

548

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


void *)) func; hd->param = param; if (pthread_create(&(hd->detectthread), NULL, __moddl_detectproc__, hd)) { hd->recfun = NULL; hd->param = NULL; pthread_mutex_unlock(&(hd->moddlhd->mutexsem)); return 0; } if (pthread_mutex_unlock(&(hd->moddlhd->mutexsem))) return 0; return 1; } /* No se pudo definir la funcin manejadora de mensajes recibidos. */ return 0; } /* Funcin modsp_poll: Verifica la llegada de un nuevo mensaje. */ int moddl_poll(moddlconn_hd *hd) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de conexin por medio de la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->moddlhd->mutexsem))) return 0; /* Verifica la recepcin de un mensaje. */ result = modplc_dlpoll(hd->moddlhd->modplchd, hd->handle); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->moddlhd->mutexsem))) return 0; /* Devuelve el resultado de la verificacin de la recepcin de un mensaje. */ return result; } /* Funcin moddl_getaddress: Devuelve la direccin fsica de la capa de enlace del modem PLC. */ int moddl_getaddress(moddl_hd *hd, unsigned char iface, moddl_phyaddr addr) { /* Variables. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Obtiene la direccin fsica. */ result = modplc_dlgetaddress(hd->modplchd, iface, addr); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0;

FernandoArielBeunza79156

549

Tesis de Grado en Ingeniera Informtica


/* Devuelve el resultado de la bsqueda. */ return result; } /* Funcin moddl_addlogaddress: Agrega una nueva direccin lgica a la capa de enlace del modem PLC. */ int moddl_addlogaddress(moddl_hd *hd, unsigned char iface, unsigned char prot, moddl_logaddr addr) { /* Variables. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Agrega una nueva direccin lgica. */ result = modplc_dladdlogaddress(hd->modplchd, iface, prot, addr); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve el resultado del agregado de la direccin lgica. */ return result; } /* Funcin moddl_dellogaddress: Elimina una direccin lgica a la capa de enlace del modem PLC. */ int moddl_dellogaddress(moddl_hd *hd, unsigned char iface, unsigned char prot, moddl_logaddr addr) { /* Variables. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Elimina una direccin lgica. */ result = modplc_dldellogaddress(hd->modplchd, iface, prot, addr); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve el resultado de la eliminacin de la direccin lgica. */ return result; } /* Funcin moddl_getphyaddress: Devuelve la direccin fsica asociada a la direccin lgica de la capa de enlace del modem PLC. */ int moddl_getphyaddress(moddl_hd *hd, unsigned char iface, unsigned char prot, moddl_logaddr laddr, moddl_phyaddr paddr) { /* Variables. */

550

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Obtiene la direccin fsica asociada a la direccin lgica. */ result = modplc_dlgetphyaddress(hd->modplchd, iface, prot, laddr, paddr); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve el resultado de la bsqueda. */ return result; } /* Funcin moddl_status: Devuelve el estado del modem PLC. */ int moddl_status(moddl_hd *hd) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Obtiene el estado del modem PLC. */ result = modplc_status(hd->modplchd); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve el resultado del modem PLC. */ return result; } /* Funcin moddl_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje de la capa de enlace del modem PLC. */ size_t moddl_getpayloadsize(moddl_hd *hd, unsigned char iface) { /* Variables. */ size_t payloadsize; /* Cantidad mxima de bytes que puede contener un mensaje. */

/* Verifica que el manejador de interfaz con la capa de enlace del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Obtiene la cantidad mxima de bytes que puede contener un

FernandoArielBeunza79156

551

Tesis de Grado en Ingeniera Informtica


mensaje. */ payloadsize = modplc_dlgetpayloadsize(hd->modplchd, iface); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve la cantidad mxima de bytes que puede contener un mensaje. */ return payloadsize; }

/* Implementacin de funciones privadas. */ /* Funcin __moddl_detectproc__: Verifica la existencia de un mensaje recibido disponible para ser ledo. */ static void *__moddl_detectproc__(void *param) { /* Variables. */ int recvflag; size_t msgsize; moddl_phyaddr addr; moddlconn_hd *hd;

/* Indicador de recepcin de un mensaje. */ /* Tamao del mensaje recibido. */ /* Direccin fsica de origen del mensaje. */ /* Manejador de conexin por medio de la capa de enlace del modem PLC. */

void (*func) (void *, moddl_phyaddr, void *, size_t, void *); unsigned char *msg;

/* Manejador de mensajes recibidos. */ /* Puntero al mensaje recibido. */

/* Carga el manejador de conexin por medio de la capa de enlace del modem PLC. */ hd = (moddlconn_hd *) param; /* Verifica la existencia de un mensaje recibido. */ while(1) { /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->moddlhd->mutexsem))) continue; /* Verifica la recepcin de un mensaje. */ func = hd->recfun; if (!func) break; recvflag = modplc_dlpoll(hd->moddlhd->modplchd, hd->handle); if (recvflag) { msg = (unsigned char *) malloc(hd->payloadsize * sizeof(unsigned char)); if (msg) msgsize = modplc_dlreceive( hd->moddlhd->modplchd, hd->handle, addr, msg, hd->payloadsize); else recvflag = 0; } /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ pthread_mutex_unlock(&(hd->moddlhd->mutexsem)); /* Verifica si se ha detectado la recepcin de un mensaje para

552

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


invocar a la funcin manejadora de mensajes recibidos. */ if (recvflag) { func(hd, addr, msg, msgsize, hd->param); free(msg); } } /* Fin de ejecucin del hilo de deteccin de recepcin. */ pthread_mutex_unlock(&(hd->moddlhd->mutexsem)); pthread_exit(0); }

C.4.4.10. Archivo modphy.h


/* modphy.h: Declaracin de funciones referentes a la interfaz de la capa fsica del modem PLC. */

#if !defined(__MODPHY_H__) #define __MODPHY_H__

/* Archivos includos necesarios. */ #include "config.h" #include <pthread.h> #include "modplc.h"

/* Definicin de tipos. */ /* Manejador de interfaz con la capa fsica del modem PLC. */ typedef struct { pthread_mutex_t mutexsem; /* Semforo de exclusin mtua. */ modplc_hd *modplchd; /* Manejador de interfaz con el modem PLC. */ struct { pthread_t detectthread; /* Manejador de hilo de deteccin de recepcin. */ void (*recfun) (void *, void *); /* Funcin manejadora de tramas capturadas. */ void *param; /* Parmetros para la funcin manejadora de tramas recibidos. */ } iface[256]; /* Tabla de interfaces fsicas. */ } modphy_hd;

/* Definicin de constantes. */ /* Tipos de seales. */ #define MODPHY_NOISESIGNAL #define MODPHY_TESTSIGNAL1 #define MODPHY_TESTSIGNAL2

0x01 0x02 0x03

/* Declaracin de funciones pblicas. */ /* Funcin modphy_init: Inicializa los recursos utilizados por la capa fsica del modem PLC. */

FernandoArielBeunza79156

553

Tesis de Grado en Ingeniera Informtica


modphy_hd *modphy_init(int, int); /* Funcin modphy_release: Libera los recursos utilizados por la capa fsica del modem PLC. */ int modphy_release(modphy_hd *); /* Funcin modphy_sndframe: Enva una trama. */ size_t modphy_sndframe(modphy_hd *, unsigned char, const void *, size_t); /* Funcin modphy_capframe: Captura una trama. */ int modphy_capframe(modphy_hd *, unsigned char, size_t); /* Funcin modphy_getframe: Obtiene una trama capturada previamente. */ size_t modphy_getframe(modphy_hd *, unsigned char, void *, size_t); /* Funcin modphy_notify: Define una funcin manejadora de tramas capturadas. */ int modphy_notify(modphy_hd *, unsigned char, void (*func)(modphy_hd *, void *), void *); /* Funcin modphy_poll: Verifica la captura de una trama. */ int modphy_poll(modphy_hd *, unsigned char); /* Funcin modphy_rsdframe: Reenva una trama. */ int modphy_rsdframe(modphy_hd *, unsigned char); /* Funcin modphy_clrbuffer: Limpia el buffer de captura de tramas. */ int modphy_clrbuffer(modphy_hd *, unsigned char); /* Funcin modphy_sensechannel: Sensa el estado del canal de comunicacin. */ int modphy_sensechannel(modphy_hd *, unsigned char, unsigned char, long int); /* Funcin modphy_gensignal: Genera la seal especificada por medio de la capa fsica del modem PLC. */ int modphy_gensignal(modphy_hd *, unsigned char, int); /* Funcin modphy_tstreceive: Realiza una prueba de recepcin. */ int modphy_tstreceive(modphy_hd *, unsigned char); /* Funcin modphy_status:

554

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Devuelve el estado del modem PLC. */ int modphy_status(modphy_hd *); /* Funcin modphy_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener una trama de la capa fsica del modem PLC. */ size_t modphy_getpayloadsize(modphy_hd *, unsigned char);

#endif

C.4.4.11. Archivo modphy.c


/* modphy.c: Implementacin de funciones referentes a la interfaz de la capa fsica del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <pthread.h> #include "modplc.h" #include "modphy.h" #include "moddl.h"

/* Declaracin de funciones privadas. */ static void *__modphy_detectproc__(void *);

/* Implementacin de funciones pblicas. */ /* Funcin modphy_init: Inicializa los recursos utilizados por la capa fsica del modem PLC. */ modphy_hd *modphy_init(int sid, int debugmode) { /* Variables. */ short int iface; modphy_hd *handle;

/* Identificadores de interfaces fsicas. */ /* Manejador de interfaz con la capa fsica del modem PLC. */

/* Crea un nuevo manejador de interfaz con la capa fsica del modem PLC. */ handle = (modphy_hd *) malloc(sizeof(modphy_hd)); if (!handle) return NULL; /* Inicializa el manejador de interfaz con la capa fsica del modem PLC. */ while(1) { /* Inicializa el manejador de interfaz con el modem PLC. */ handle->modplchd = modplc_init(sid, MODPLC_PHYSICALLAYER, debugmode); if (!handle->modplchd) break; /* Inicializa el manejador de tramas capturadas de cada una de las interfaces fsicas. */ for(iface = 0; iface < 256; iface ++) {

FernandoArielBeunza79156

555

Tesis de Grado en Ingeniera Informtica


handle->iface[iface].recfun = NULL; handle->iface[iface].param = NULL; } /* Inicializa semforo. */ if (pthread_mutex_init(&(handle->mutexsem), NULL)) break; if (pthread_mutex_unlock(&(handle->mutexsem))) break; /* Devuelve el manejador creado. */ return handle; } /* No se pudo inicializar la interfaz con la capa fsica del modem PLC. */ pthread_mutex_destroy(&(handle->mutexsem)); modplc_release(handle->modplchd); free(handle); return NULL; } /* Funcin modphy_release: Libera los recursos utilizados por la capa fsica del modem PLC. */ int modphy_release(modphy_hd *hd) { /* Variables. */ short int iface;

/* Identificadores de interfaces fsicas. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Libera el manejador de captura de tramas. */ for(iface = 0; iface < 256; iface ++) modphy_notify(hd, (unsigned char) (iface & 0x00ff), NULL, NULL); /* Libera los recursos utilizados por el semforo de exclusin mtua. */ if (pthread_mutex_destroy(&(hd->mutexsem))) return 0; /* Libera la interfaz con el modem PLC. */ modplc_release(hd->modplchd); /* Libera los recursos utilizados por la interfaz con la capa fsica del modem PLC. */ free(hd); /* xito. */ return 1; } /* Funcin modphy_sndframe: Enva una trama. */ size_t modphy_sndframe(modphy_hd *hd, unsigned char iface, const void *frame, size_t framesize) { /* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Enva una trama. */ framesize = modplc_physndframe(hd->modplchd, iface, frame, framesize);

556

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve la cantidad de bytes envados. */ return framesize; } /* Funcin modphy_capframe: Captura una trama. */ int modphy_capframe(modphy_hd *hd, unsigned char iface, size_t framesize) { /* Variables. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Captura una trama. */ result = modplc_phycapframe(hd->modplchd, iface, framesize); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve el resultado de la solicitud de captura de una trama. */ return result; } /* Funcin modphy_getframe: Obtiene una trama capturada previamente. */ size_t modphy_getframe(modphy_hd *hd, unsigned char iface, void *frame, size_t framesize) { /* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Obtiene una trama capturada previamente. */ framesize = modplc_phygetframe(hd->modplchd, iface, frame, framesize); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve la cantidad de bytes recibidos. */ return framesize; } /* Funcin modphy_notify: Define una funcin manejadora de tramas capturadas. */ int modphy_notify(modphy_hd *hd, unsigned char iface, void (*func)(modphy_hd *, void *), void *param) { /* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0;

FernandoArielBeunza79156

557

Tesis de Grado en Ingeniera Informtica


/* Si la funcin manejadora es nula y no hay ninguna funcin manejadora definida previamente no se hace nada. */ if ((!func) && (!hd->iface[iface].recfun)) return 1; /* Si la funcin manejadora no es nula y hay una funcin manejadora previamente definida actualiza la funcin manejadora. */ if ((func) && (hd->iface[iface].recfun)) { if (pthread_mutex_lock(&(hd->mutexsem))) return 0; hd->iface[iface].recfun = (void (*)(void *, void *)) func; hd->iface[iface].param = param; if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; return 1; } /* Si la funcin manejadora es nula y hay una funcin manejadora definida previamente se elimina esta ltima. */ if ((!func) && (hd->iface[iface].recfun)) { if (pthread_mutex_lock(&(hd->mutexsem))) return 0; hd->iface[iface].recfun = (void (*)(void *, void *)) NULL; hd->iface[iface].param = param; if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; if (pthread_join(hd->iface[iface].detectthread, NULL)) return 0; return 1; } /* Si la funcin manejadora no es nula y no hay una funcin manejadora previamente definida se define la nueva funcin manejadora. */ if ((func) && (!hd->iface[iface].recfun)) { if (pthread_mutex_lock(&(hd->mutexsem))) return 0; hd->iface[iface].recfun = (void (*)(void *, void *)) func; hd->iface[iface].param = param; if (pthread_create(&(hd->iface[iface].detectthread), NULL, __modphy_detectproc__, hd)) { hd->iface[iface].recfun = NULL; hd->iface[iface].param = NULL; pthread_mutex_unlock(&(hd->mutexsem)); return 0; } if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; return 1; } /* No se pudo definir la funcin manejadora de tramas capturadas. */ return 0; } /* Funcin modphy_poll: Verifica la captura de una trama. */ int modphy_poll(modphy_hd *hd, unsigned char iface) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Verifica la captura de una trama. */

558

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


result = modplc_phypoll(hd->modplchd, iface); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve el resultado de la verificacin de la captura de una trama. */ return result; } /* Funcin modphy_rsdframe: Reenva una trama. */ int modphy_rsdframe(modphy_hd *hd, unsigned char iface) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Reenva una trama. */ result = modplc_phyrsdframe(hd->modplchd, iface); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve el resultado del reenvo de una trama. */ return result; } /* Funcin modphy_clrbuffer: Limpia el buffer de captura de tramas. */ int modphy_clrbuffer(modphy_hd *hd, unsigned char iface) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Limpia el buffer de captura de tramas. */ result = modplc_phyclrbuffer(hd->modplchd, iface); /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve el resultado de la limpieza del buffer de captura de tramas. */ return result; } /* Funcin modphy_sensechannel: Sensa el estado del canal de comunicacin.

FernandoArielBeunza79156

559

Tesis de Grado en Ingeniera Informtica


*/ int modphy_sensechannel(modphy_hd *hd, unsigned char iface, unsigned char level, long int waittime) { /* Variables. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Sensa el estado del canal de comunicacin. */ result = modplc_physensechannel(hd->modplchd, iface, level, waittime); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve el resultado del sensado del canal de comunicacin. */ return result; } /* Funcin modphy_gensignal: Genera la seal especificada por medio de la capa fsica del modem PLC. */ int modphy_gensignal(modphy_hd *hd, unsigned char iface, int sig) { /* Variables. */ int result; /* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Genera la seal especificada. */ result = modplc_phygensignal(hd->modplchd,iface , sig); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve el resultado de la generacin de la seal. */ return result; } /* Funcin modphy_tstreceive: Realiza una prueba de recepcin. */ int modphy_tstreceive(modphy_hd *hd, unsigned char iface) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0;

560

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Realiza una prueba de recepcin. */ result = modplc_phytstreceive(hd->modplchd, iface); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve el resultado de la prueba de recepcin. */ return result; } /* Funcin modphy_status: Devuelve el estado del modem PLC. */ int modphy_status(modphy_hd *hd) { /* Variables. */ int result;

/* Resultado de la operacin. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Obtiene el estado del modem PLC. */ result = modplc_status(hd->modplchd); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve el resultado del modem PLC. */ return result; } /* Funcin modphy_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener una trama de la capa fsica del modem PLC. */ size_t modphy_getpayloadsize(modphy_hd *hd, unsigned char iface) { /* Variables. */ size_t payloadsize; /* Cantidad mxima de bytes que puede contener una trama. */

/* Verifica que el manejador de interfaz con la capa fsica del modem PLC exista. */ if (!hd) return 0; /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) return 0; /* Obtiene la cantidad mxima de bytes que puede contener una trama. */ payloadsize = modplc_phygetpayloadsize(hd->modplchd, iface); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ if (pthread_mutex_unlock(&(hd->mutexsem))) return 0; /* Devuelve la cantidad mxima de bytes que puede contener una trama. */ return payloadsize; }

FernandoArielBeunza79156

561

Tesis de Grado en Ingeniera Informtica


/* Implementacin de funciones privadas. */ /* Funcin __modphy_detectproc__: Verifica la existencia de una trama capturada disponible para ser leda. */ static void *__modphy_detectproc__(void *param) { /* Variables. */ int captureflag; short int i; unsigned char iface; modphy_hd *hd; void (*func)(void *, void *);

/* Indicador de captura de una trama. */ /* Contador. */ /* Identificadores de interfaces fsicas. */ /* Manejador de interfaz con la capa fsica del modem PLC. */ /* Manejador de captura de tramas. */

/* Carga el manejador de interfaz con la capa fsica del modem PLC. */ hd = (modphy_hd *) param; /* Obtiene el identificador de interface fsica asociado al hilo de deteccin de recepcin. */ iface = 0; if (pthread_mutex_lock(&(hd->mutexsem))) return 0; for(i = 0; i < 256; i++) { if (!pthread_equal(hd->iface[i].detectthread, pthread_self())) continue; iface = (unsigned char) (i & 0x00ff); break; } pthread_mutex_unlock(&(hd->mutexsem)); if (i > 255) return 0; /* Verifica la existencia de una trama capturada. */ while(1) { /* Espera el permiso para poder acceder a la interfaz con el modem PLC. */ if (pthread_mutex_lock(&(hd->mutexsem))) continue; /* Verifica la captura de una trama. */ func = hd->iface[iface].recfun; if (!func) break; captureflag = modplc_phypoll(hd->modplchd, iface); /* Permite a otro hilos el acceso a la interfaz del modem PLC. */ pthread_mutex_unlock(&(hd->mutexsem)); /* Verifica si se ha detectado la captura de una trama para invocar al manejador de trama capturadas. */ if (captureflag) func(hd, hd->iface[iface].param); } /* Fin de ejecucin del hilo de deteccin de recepcin. */ pthread_mutex_unlock(&(hd->mutexsem)); pthread_exit(0); }

C.4.4.12. Archivo modrv.h


/* moddrv.h:

562

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Declaracin de funciones referentes al driver del modem PLC. */

#if !defined(__MODDRV_H__) #define __MODDRV_H__

/* Archivos includos necesarios. */ #include "config.h" #include "modphy.h" #include "moddl.h" #include "modsp.h"

/* Definicin de tipos. */ /* Estructura del manejador del driver del modem PLC. */ typedef struct { int port; int layer; int debugmode; int stopflag;

/* /* /* /*

unsigned long int clients; modsp_hd *sphd; moddl_hd *dlhd; modphy_hd *phyhd; } moddrv_hd;

/* /* /* /*

Identificador de puerto. */ Capa del modem PLC utilizada. */ Indicador de modo depuracin. */ Indicador de detencin de ejecucin del driver del modem PLC. */ Cantidad de clientes activos. */ Manejador de interfaz con la capa de sesin del modem PLC. */ Manejador de interfaz con la capa de enlace del modem PLC. */ Manejador de interfaz con la capa fsica del modem PLC. */

/* Declaracin de funciones pblicas. */ /* Funcin moddrv_init: Inicializa los recursos utilizados por el driver del modem PLC. */ moddrv_hd *moddrv_init(int, int); /* Funcin moddrv_release: Libera los recursos utilizados por el driver del modem PLC. */ int moddrv_release(moddrv_hd *); /* Funcin moddrv_run: Ejecuta el driver del modem PLC. */ int moddrv_run(moddrv_hd *); /* Funcin moddrv_stop: Detiene la ejecucin del driver del modem PLC. */ int moddrv_stop(moddrv_hd *);

#endif

C.4.4.13. Archivo moddrv.c


/*

FernandoArielBeunza79156

563

Tesis de Grado en Ingeniera Informtica


moddrv.c: Implementacin de funciones referentes al driver del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdio.h> #include <unistd.h> #include <string.h> #include <pthread.h> #include <errno.h> #include <sys/socket.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/un.h> #include "modphy.h" #include "moddl.h" #include "modsp.h" #include "moddrv.h"

/* Definicin de tipos. */ /* Estructura de informacin compartida entre hilos de ejecucin. */ typedef struct { int hq; /* Manejador mensajes. pthread_mutex_t hm; /* Manejador exclusin moddrv_hd *hd; /* Manejador PLC. */ } __moddrv_shareinf__;

de cola de */ de semforo de mutua. */ del driver del modem

/* Declaracin de funciones privadas. */ static void *__moddrv_clientthread__(void *); static int __moddrv_phyclient__(moddrv_hd *, int, pthread_mutex_t); static int __moddrv_dlclient__(moddrv_hd *, int, pthread_mutex_t); static int __moddrv_spclient__(moddrv_hd *, int, pthread_mutex_t); static int __moddrv_send__(int, const void *, size_t); static int __moddrv_receive__(int, void *, size_t);

/* Implementacin de funciones pblicas. */ /* Funcin moddrv_init: Inicializa los recursos utilizados por el driver del modem PLC. */ moddrv_hd *moddrv_init(int sid, int debugmode) { /* Variables. */ moddrv_hd *handle;

/* Manejador del driver del modem PLC. */

/* Crea un nuevo manejador del driver del modem PLC. */ handle = (moddrv_hd *) malloc(sizeof(moddrv_hd)); if (!handle) return NULL; /* Inicializa el driver del modem PLC. */ handle->port = sid; handle->layer = 0; handle->clients = 0; handle->debugmode = debugmode; handle->stopflag = 0; /* Devuelve el manejador creado. */ return handle;

564

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


} /* Funcin moddrv_release: Libera los recursos utilizados por el driver del modem PLC. */ int moddrv_release(moddrv_hd *hd) { /* Verifica que el manejador del driver del modem PLC exista. */ if (!hd) return 0; /* Libera los recursos utilizados el driver del modem PLC. */ free(hd); /* xito. */ return 1; } /* Funcin moddrv_run: Ejecuta el driver del modem PLC. */ int moddrv_run(moddrv_hd *hd) { /* Variables. */ int hl; int hq; pthread_mutex_t hm; pthread_t cthread; char qname[256]; __moddrv_shareinf__ sinf; socklen_t clilen; struct sockaddr_un cliaddr; struct sockaddr_un servaddr;

/* Manejador de espera de conexin. */ /* Manejador de cola de mensajes. */ /* Manejador de semforo de exclusin mutua. */ /* Manejador de hilo. */ /* Nombre de la cola de mensajes. */ /* Informacin compartida. */ /* Longitud de direccin del cliente. */ /* Direccin del cliente. */ /* Direccin del servidor. */

/* Verifica que el manejador del driver del modem PLC exista. */ if (!hd) return 0; /* Inicializa semforo. */ if (pthread_mutex_init(&hm, NULL)) return 0; if (pthread_mutex_unlock(&hm)) return 0; /* Procesa las solicitudes de los clientes. */ hd->layer = 0; hd->clients = 0; sprintf(qname, "/tmp/modemplc%i.str", hd->port); while(1) { /* Crea una nueva cola de mensajes. */ hl = socket(AF_LOCAL, SOCK_STREAM, 0); if (hl < 0) break; unlink(qname); bzero(&servaddr, sizeof(servaddr)); servaddr.sun_family = AF_LOCAL; strcpy(servaddr.sun_path, qname); if (bind(hl, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) break; if (listen(hl, 20) < 0) break; if (chmod(qname, 0777) < 0) break; /* Espera la conexin de un nuevo cliente. */ if (hd->stopflag) break; clilen = sizeof(cliaddr); hq = accept(hl, (struct sockaddr *) &cliaddr, &clilen);

FernandoArielBeunza79156

565

Tesis de Grado en Ingeniera Informtica


if (hq < 0) { if (errno == EINTR) continue; else break; } /* Crea un nuevo hilo para atender las solicitudes del nuevo cliente. */ sinf.hd = hd; sinf.hq = hq; sinf.hm = hm; if (pthread_create(&cthread, NULL, __moddrv_clientthread__, (void *) &sinf)) { close(hq); continue; } if (pthread_detach(cthread)) close(hq); } /* Fin de ejecucin del driver del modem PLC. */ pthread_mutex_destroy(&hm); close(hl); unlink(qname); return 1; } /* Funcin moddrv_stop: Detiene la ejecucin del driver del modem PLC. */ int moddrv_stop(moddrv_hd *hd) { /* Variables. */ int hq; int layer; int result; struct sockaddr_un servaddr;

/* Manejador de cola de mensajes. */ /* Capa que se solicita utilizar. */ /* Respuesta a la solicitud. */ /* Direccin del servidor. */

/* Verifica que el manejador del driver del modem PLC exista. */ if (!hd) return 0; /* Abre una conexin con la cola de mensajes del driver del modem PLC. */ hq = socket(AF_LOCAL, SOCK_STREAM, 0); if (hq < 0) return 0; bzero(&servaddr, sizeof(servaddr)); servaddr.sun_family = AF_LOCAL; sprintf(servaddr.sun_path, "/tmp/modemplc%i.str", hd->port); if (connect(hq, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) return 0; /* Solicita detener la ejecucin del driver del modem PLC. */ layer = 0; result = 0; if (__moddrv_send__(hq, &layer, sizeof(layer))) { if (__moddrv_receive__(hq, &result, sizeof(result))) result = 1; } if (!result) { close(hq); return 0; }

566

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Cierra la conexin con al cola de mensajes del driver del modem PLC. */ close(hq); return 1; }

/* Implementacin de funciones privadas. */ /* Funcin __moddrv_clientthread__: Atiene a los clientes del driver del modem PLC. */ static void *__moddrv_clientthread__(void *param) { /* Variables. */ int hq; pthread_mutex_t hm; int layer; int result; moddrv_hd *hd; __moddrv_shareinf__ *sinf;

/* Manejador de cola de mensajes. */ /* Manejador de semforo de exclusin mutua. */ /* Capa que se solicita utilizar. */ /* Respuesta a la solicitud. */ /* Manejador del driver del modem PLC. */ /* Informacin compartida. */

/* Carga el manejador de cola de mensajes y el manejador del driver del modem PLC. */ sinf = (__moddrv_shareinf__ *) param; hq = sinf->hq; hd = sinf->hd; hm = sinf->hm; /* Espera el permiso para poder acceder a los recursos del driver del modem PLC. */ if (pthread_mutex_lock(&hm)) pthread_exit(0); /* Recibe la capa a la cual el cliente quiere acceder. */ while(!__moddrv_receive__(hq, &layer, sizeof(layer))); /* Verifica si se solicita detener la ejecucin del driver del modem PLC. */ if (!layer) { result = 1; hd->stopflag = 1; __moddrv_send__(hq, &result, sizeof(result)); pthread_mutex_unlock(&hm); close(hq); pthread_exit(0); } /* Verifica si es vlida la solicitud. */ result = 0; if ((layer >= 1) && (layer <= 3)) { if (!hd->layer) hd->layer = layer; if (hd->layer == layer) result = 1; } /* Verifica si es necesario inicializar alguna interfaz. */ if ((result) && (!hd->clients)) { /* Inicializa la interfaz de la capa fsica del modem PLC. */ if (layer == 1) { hd->phyhd = modphy_init(hd->port, hd->debugmode); if (!hd->phyhd) result = 0; } /* Inicializa la interfaz de la capa de enlace del modem

FernandoArielBeunza79156

567

Tesis de Grado en Ingeniera Informtica


PLC. */ else if (layer == 2) { hd->dlhd = moddl_init(hd->port, hd->debugmode); if (!hd->dlhd) result = 0; } /* Inicializa la interfaz de la capa de sesin del modem PLC. */ else if (layer == 3) { hd->sphd = modsp_init(hd->port, hd->debugmode); if (!hd->sphd) result = 0; } } /* Enva el resultado de la solicitud. */ __moddrv_send__(hq, &result, sizeof(result)); if (!result) { if (!hd->clients) hd->layer = 0; pthread_mutex_unlock(&hm); close(hq); pthread_exit(0); } /* Agrega un nuevo cliente. */ hd->clients ++; /* Permite a otro hilos el acceso a los recursos del driver del modem PLC. */ pthread_mutex_unlock(&hm); /* Verifica si el cliente solicit acceder a la capa fsica. */ if (layer == 1) __moddrv_phyclient__(hd, hq, hm); /* Verifica si el cliente solicit acceder a la capa de enlace. */ else if (layer == 2) __moddrv_dlclient__(hd, hq, hm); /* Verifica si el cliente solicit acceder a la capa de aplicacin. */ else if (layer == 3) __moddrv_spclient__(hd, hq, hm); /* Espera el permiso para poder acceder a los recursos del driver del modem PLC. */ pthread_mutex_lock(&hm); /* Elimina un cliente. */ hd->clients --; /* Verifica si es necesario liberar alguna interfaz. */ if (!hd->clients) { /* Libera la interfaz de la capa fsica del modem PLC. */ if (layer == 1) modphy_release(hd->phyhd); /* Libera la interfaz de la capa de enlace del modem PLC. */ else if (layer == 2) moddl_release(hd->dlhd); /* Libera la interfaz de la capa de sesin del modem PLC. */ else if (layer == 3) modsp_release(hd->sphd); /* No se esta utilizando ninguna capa. */ hd->layer = 0; } /* Permite a otro hilos el acceso a los recursos del driver del modem PLC. */ pthread_mutex_unlock(&hm);

568

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Fin de ejecucin del hilo de deteccin de recepcin. */ close(hq); return 0; } /* Funcin __moddrv_phyclient__: Procesa las solicitudes de los clientes destinadas a la capa fsica del modem PLC. */ static int __moddrv_phyclient__(moddrv_hd *hd, int hq, pthread_mutex_t hm) { /* Variables. */ int op; /* Cdigo de operacin. */ int sig; /* Tipo de seal. */ int result; /* Respuesta a la solicitud. */ size_t size; /* Cantidad de bytes. */ unsigned char iface; /* Identificador de interfaz fsica. */ unsigned char level; /* Nivel de seal. */ long int waittime; /* Tiempo de espera. */ unsigned char *frame; /* Puntero a la trama recibida. */

/* Procesa solicitudes destinadas a la capa fsica del modem PLC. */ while(!hd->stopflag) { /* Recibe el cdigo de operacin. */ if (!__moddrv_receive__(hq, &op, sizeof(op))) continue; /* Espera el permiso para poder acceder a los recursos del driver del modem PLC. */ pthread_mutex_lock(&hm); /* Solicita terminar la conexin. */ if (op == MODDRVPHY_RELEASE) { result = 1; if (!__moddrv_send__(hq, &result, sizeof(result))) continue; break; } /* Solicita el envo de una trama. */ else if (op == MODDRVPHY_SNDFRAME) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Recibe el tamao de la trama. */ if (!__moddrv_receive__(hq, &size, sizeof(size))) continue; /* Recibe la trama. */ frame = (unsigned char *) malloc(size * sizeof(unsigned char)); if (!frame) continue; if (!__moddrv_receive__(hq, frame, size)) { free(frame); continue; } /* Enva la trama. */ size = modphy_sndframe(hd->phyhd, iface, frame, size); free(frame); /* Enva la cantidad de bytes enviados. */ if (!__moddrv_send__(hq, &size, sizeof(size))) continue; }

FernandoArielBeunza79156

569

Tesis de Grado en Ingeniera Informtica


/* Solicita la captura de una trama. */ else if (op == MODDRVPHY_CAPFRAME) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Recibe el tamao de la trama. */ if (!__moddrv_receive__(hq, &size, sizeof(size))) continue; /* Catura una trama. */ result = modphy_capframe(hd->phyhd, iface, size); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita la lectura de una trama capturada. */ else if (op == MODDRVPHY_GETFRAME) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Recibe el tamao de la trama. */ if (!__moddrv_receive__(hq, &size, sizeof(size))) continue; /* Catura una trama. */ frame = (unsigned char *) malloc(size * sizeof(unsigned char)); if (!frame) continue; size = modphy_getframe(hd->phyhd, iface, frame, size); /* Enva la trama leda. */ if (!__moddrv_send__(hq, frame, size)) { free(frame); continue; } free(frame); /* Enva la cantidad de bytes ledos. */ if (!__moddrv_send__(hq, &size, sizeof(size))) continue; } /* Solicita la verificacin de la captura de una trama. */ else if (op == MODDRVPHY_POLL) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Verifica de la captura de una trama. */ result = modphy_poll(hd->phyhd, iface); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita el reenvo de una trama. */ else if (op == MODDRVPHY_RSDFRAME) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Reenva una trama. */ result = modphy_rsdframe(hd->phyhd, iface);

570

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita la limpieza del buffer de captura de tramas. */ else if (op == MODDRVPHY_CLRBUFFER) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Limpia el buffer de captura de tramas. */ result = modphy_clrbuffer(hd->phyhd, iface); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita el sensado del canal de comunicacin. */ else if (op == MODDRVPHY_SENSECHANNEL) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Recibe el nivel de seal. */ if (!__moddrv_receive__(hq, &level, sizeof(level))) continue; /* Recibe el tiempo de espera. */ if (!__moddrv_receive__(hq, &waittime, sizeof(waittime))) continue; /* Sensa el estado del canal de comunicacin. */ result = modphy_sensechannel(hd->phyhd, iface, level, waittime); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita la generacin de una seal. */ else if (op == MODDRVPHY_GENSIGNAL) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Recibe el tipo de seal. */ if (!__moddrv_receive__(hq, &sig, sizeof(sig))) continue; /* Genera la seal solicitada. */ result = modphy_gensignal(hd->phyhd, iface, sig); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita realizar una prueba de recepcin. */ else if (op == MODDRVPHY_TSTRECEIVE) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Realiza la prueba de recepcin. */ result = modphy_tstreceive(hd->phyhd, iface); /* Enva el resultado de la solicitud. */

FernandoArielBeunza79156

571

Tesis de Grado en Ingeniera Informtica


if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita verifica el estado del modem PLC. */ else if (op == MODDRVPHY_STATUS) { /* Verifica el estado del modem PLC. */ result = modphy_status(hd->phyhd); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita la cantidad mxima de bytes que puede contener una trama. */ else if (op == MODDRVPHY_GETPAYLOADSIZE) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Obtiene la cantidad mxima de bytes que puede contener una trama. */ size = modphy_getpayloadsize(hd->phyhd, iface); if (!__moddrv_send__(hq, &size, sizeof(size))) continue; } /* Solicitud desconocida. */ else { result = 0; if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Permite a otro hilos el acceso a los recursos del driver del modem PLC. */ pthread_mutex_unlock(&hm); } pthread_mutex_unlock(&hm); return 0; } /* Funcin __moddrv_dlclient__: Procesa las solicitudes de los clientes destinadas a la capa de enlace del modem PLC. */ static int __moddrv_dlclient__(moddrv_hd *hd, int hq, pthread_mutex_t hm) { /* Variables. */ int op; /* Cdigo de operacin. */ int result; /* Respuesta a la solicitud. */ unsigned char prot; /* Identificador de protocolo. */ unsigned char prio; /* Prioridad del mensaje. */ unsigned char iface; /* Identificador de interfaz fsica. */ size_t size; /* Cantidad de bytes. */ moddlconn_hd *dlconnhd; /* Manejador de conexin por medio de la capa de enlace del modem PLC. */ moddl_logaddr laddr; /* Direccin lgica. */ moddl_phyaddr paddr; /* Direccin fsica. */ unsigned char *msg; /* Puntero al mensaje recibido. */

/* Procesa solicitudes destinadas a la capa de enlace del modem PLC. */ dlconnhd = NULL; while(!hd->stopflag) { /* Recibe el cdigo de operacin. */

572

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


if (!__moddrv_receive__(hq, &op, sizeof(op))) continue; /* Espera el permiso para poder acceder a los recursos del driver del modem PLC. */ pthread_mutex_lock(&hm); /* Solicita cerrar la conexin. */ if (op == MODDRVDL_CLOSE) { result = 0; if (moddl_close(dlconnhd)) result = 1; if (!__moddrv_send__(hq, &result, sizeof(result))) continue; break; } /* Solicita abrir la conexin. */ else if (op == MODDRVDL_OPEN) { /* Abre la conexin si no fue abierta anteriormente. */ result = 0; if (!dlconnhd) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Recibe el identificador de protocolo. */ if (!__moddrv_receive__(hq, &prot, sizeof(prot))) continue; /* Abre la conexin. */ dlconnhd = moddl_open(hd->dlhd, iface, prot); if (dlconnhd) result = 1; } /* Devuelve el resultado de la operacin. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita enviar un mensaje. */ else if (op == MODDRVDL_SEND) { /* Enva un mensaje. */ size = 0; if (dlconnhd) { /* Recibe la direccin destinataria. */ if (!__moddrv_receive__(hq, paddr, sizeof(paddr))) continue; /* Recibe la prioridad del mensaje. */ if (!__moddrv_receive__(hq, &prio, sizeof(prio))) continue; /* Recibe el tamao del mensaje. */ if (!__moddrv_receive__(hq, &size, sizeof(size))) continue; /* Recibe el mensaje. */ msg = (unsigned char *) malloc(size * sizeof(unsigned char)); if (!msg) continue; if (!__moddrv_receive__(hq, msg, size)) { free(msg);

FernandoArielBeunza79156

573

Tesis de Grado en Ingeniera Informtica


continue; } /* Enva el mensaje. */ size = moddl_send(dlconnhd, paddr, prio, msg, size); free(msg); } /* Devuelve la cantidad de bytes enviados. */ if (!__moddrv_send__(hq, &size, sizeof(size))) continue; } /* Solicita recibir un mensaje. */ else if (op == MODDRVDL_RECEIVE) { /* Recibe un mensaje. */ size = 0; msg = NULL; if (dlconnhd) { /* Recibe el tamao del mensaje. */ if (!__moddrv_receive__(hq, &size, sizeof(size))) continue; /* Recibe el mensaje. */ msg = (unsigned char *) malloc(size * sizeof(unsigned char)); if (!msg) continue; size = moddl_receive(dlconnhd, paddr, msg, size); } /* Devuelve la cantidad de bytes recibidos. */ if (!__moddrv_send__(hq, &size, sizeof(size))) { if (msg) free(msg); continue; } if (!size) { free(msg); continue; } /* Enva la direccin de origen del mensaje. */ if (!__moddrv_send__(hq, paddr, sizeof(paddr))) { free(msg); continue; } /* Enva la direccin de origen del mensaje. */ if (!__moddrv_send__(hq, msg, size)) { free(msg); continue; } free(msg); } /* Solicita la verificacin de un mensaje. */ else if (op == MODDRVDL_POLL) { /* Verifica de la recepcin de un mensaje. */ result = 0; if (dlconnhd) result = moddl_poll(dlconnhd); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; }

574

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Solicita la direccin fsica del modem PLC. */ else if (op == MODDRVDL_GETADDRESS) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Obtiene la direccin fsica. */ result = moddl_getaddress(hd->dlhd, iface, paddr); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; if (!result) continue; /* Enva la direccin fsica solicitada. */ if (!__moddrv_send__(hq, paddr, sizeof(paddr))) continue; } /* Solicita agregar una nueva direccin lgica. */ else if (op == MODDRVDL_ADDLOGADDRESS) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Recibe el identificador de protocolo. */ if (!__moddrv_receive__(hq, &prot, sizeof(prot))) continue; /* Recibe la direccin lgica. */ if (!__moddrv_receive__(hq, &laddr, sizeof(laddr))) continue; /* Agrega la direccin lgica. */ result = moddl_addlogaddress(hd->dlhd, iface, prot, laddr); /* Devuelve el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita eliminar una direccin lgica. */ else if (op == MODDRVDL_DELLOGADDRESS) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Recibe el identificador de protocolo. */ if (!__moddrv_receive__(hq, &prot, sizeof(prot))) continue; /* Recibe la direccin lgica. */ if (!__moddrv_receive__(hq, &laddr, sizeof(laddr))) continue; /* Elimina la direccin lgica. */ result = moddl_dellogaddress(hd->dlhd, iface, prot, laddr); /* Devuelve el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita obtener la direccin fsica asociada a la direccin lgica. */ else if (op == MODDRVDL_GETPHYADDRESS) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface)))

FernandoArielBeunza79156

575

Tesis de Grado en Ingeniera Informtica


continue; /* Recibe el identificador de protocolo. */ if (!__moddrv_receive__(hq, &prot, sizeof(prot))) continue; /* Recibe la direccin lgica. */ if (!__moddrv_receive__(hq, &laddr, sizeof(laddr))) continue; /* Obtiene la direccin lgica. */ result = moddl_getphyaddress(hd->dlhd, iface, prot, laddr, paddr); /* Devuelve el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; if (!result) continue; /* Enva la direccin fsica. */ if (!__moddrv_send__(hq, paddr, sizeof(paddr))) continue; } /* Solicita verifica el estado del modem PLC. */ else if (op == MODDRVDL_STATUS) { /* Verifica el estado del modem PLC. */ result = moddl_status(hd->dlhd); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita la cantidad mxima de bytes que puede contener un mensaje. */ else if (op == MODDRVDL_GETPAYLOADSIZE) { /* Recibe el identificador de interfaz fsica. */ if (!__moddrv_receive__(hq, &iface, sizeof(iface))) continue; /* Obtiene la cantidad mxima de bytes que puede contener un mensaje. */ size = moddl_getpayloadsize(hd->dlhd, iface); /* Devuelve la cantidad mxima de bytes que puede contener un mensaje. */ if (!__moddrv_send__(hq, &size, sizeof(size))) continue; } /* Solicitud desconocida. */ else { result = 0; if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Permite a otro hilos el acceso a los recursos del driver del modem PLC. */ pthread_mutex_unlock(&hm); } pthread_mutex_unlock(&hm); return 0; } /* Funcin __moddrv_spclient__: Procesa las solicitudes de los clientes destinadas a la capa de sesin del modem PLC. */

576

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


static int __moddrv_spclient__(moddrv_hd *hd, int hq, pthread_mutex_t hm) { /* Variables. */ int op; /* Cdigo de operacin. */ int result; /* Respuesta a la solicitud. */ size_t size; /* Cantidad de bytes. */ modsp_grpid grpid; /* Identificador de grupo. */ unsigned char nosec; /* Indicador de mensaje fuera de secuencia. */ unsigned char *msg; /* Puntero al mensaje recibido. */

/* Procesa solicitudes destinadas a la capa de aplicacin del modem PLC. */ while(!hd->stopflag) { /* Recibe el cdigo de operacin. */ if (!__moddrv_receive__(hq, &op, sizeof(op))) continue; /* Espera el permiso para poder acceder a los recursos del driver del modem PLC. */ pthread_mutex_lock(&hm); /* Solicita terminar la conexin. */ if (op == MODDRVSP_RELEASE) { result = 1; if (!__moddrv_send__(hq, &result, sizeof(result))) continue; break; } /* Solicita el registro del dispositivo como publicador. */ else if (op == MODDRVSP_PUBLISH) { /* Recibe el identificador de grupo. */ if (!__moddrv_receive__(hq, &grpid, sizeof(grpid))) continue; /* Registra el dispositivo como publicador. */ result = modsp_publish(hd->sphd, grpid); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita el registro del dispositivo como suscriptor. */ else if (op == MODDRVSP_SUBSCRIBE) { /* Recibe el identificador de grupo. */ if (!__moddrv_receive__(hq, &grpid, sizeof(grpid))) continue; /* Registra el dispositivo como suscriptor. */ result = modsp_subscribe(hd->sphd, grpid); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita la desvinculacin del dispositivo a un grupo de difusin. */ else if (op == MODDRVSP_LEAVE) { /* Recibe el identificador de grupo. */ if (!__moddrv_receive__(hq, &grpid, sizeof(grpid))) continue; /* Desvincula el dispositivo de un grupo de difusin. */ result = modsp_leave(hd->sphd, grpid); /* Enva el resultado de la solicitud. */

FernandoArielBeunza79156

577

Tesis de Grado en Ingeniera Informtica


if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita el envo de un mensaje. */ else if (op == MODDRVSP_SEND) { /* Recibe el identificador de grupo. */ if (!__moddrv_receive__(hq, &grpid, sizeof(grpid))) continue; /* Recibe el indicador de mensaje fuera de secuencia. */ if (!__moddrv_receive__(hq, &nosec, sizeof(nosec))) continue; /* Recibe el tamao del mensaje. */ if (!__moddrv_receive__(hq, &size, sizeof(size))) continue; /* Enva el mensaje solicitado. */ while(1) { /* Recibe el mensaje. */ msg = (unsigned char *) malloc(size * sizeof(unsigned char)); if (!msg) { size = 0; break; } if (!__moddrv_receive__(hq, msg, size)) { size = 0; break; } /* Enva el mensaje. */ size = modsp_send(hd->sphd, grpid, nosec, msg, size); break; } /* Enva la cantidad de bytes enviados. */ if (!__moddrv_send__(hq, &size, sizeof(size))) continue; } /* Solicita la recepcin de un mensaje. */ else if (op == MODDRVSP_RECEIVE) { /* Recibe la cantidad de bytes que se desea recibir del mensaje. */ if (!__moddrv_receive__(hq, &size, sizeof(size))) continue; /* Recibe el mensaje. */ msg = (unsigned char *) malloc(size * sizeof(unsigned char)); if (msg) size = modsp_receive(hd->sphd, &grpid, msg, size); else size = 0; /* Enva la cantidad de bytes recibidos. */ if (!__moddrv_send__(hq, &size, sizeof(size))) continue; if (!size) continue; /* Enva el indentificador del grupo de difusin por el cual se recibi el mensaje. */ if (!__moddrv_send__(hq, &grpid, sizeof(grpid)))

578

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


{ free(msg); continue; } /* Enva el mensaje recibido. */ if (!__moddrv_send__(hq, msg, size)) { free(msg); continue; } free(msg); } /* Solicita la verificacin de la recepcin de un mensaje. */ else if (op == MODDRVSP_POLL) { /* Verifica de la recepcin de un mensaje. */ result = modsp_poll(hd->sphd); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita verifica el estado del modem PLC. */ else if (op == MODDRVSP_STATUS) { /* Verifica el estado del modem PLC. */ result = modsp_status(hd->sphd); /* Enva el resultado de la solicitud. */ if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Solicita la cantidad mxima de bytes que puede contener un mensaje. */ else if (op == MODDRVSP_GETPAYLOADSIZE) { size = modsp_getpayloadsize(hd->sphd); if (!__moddrv_send__(hq, &size, sizeof(size))) continue; } /* Solicitud desconocida. */ else { result = 0; if (!__moddrv_send__(hq, &result, sizeof(result))) continue; } /* Permite a otro hilos el acceso a los recursos del driver del modem PLC. */ pthread_mutex_unlock(&hm); } pthread_mutex_unlock(&hm); return 0; } /* Funcin __moddrv_send__: Enva datos por medio de la cola de mensajes. */ static int __moddrv_send__(int hq, const void *stream, size_t size) { /* Variables. */ size_t sent; /* Cantidad de bytes enviados. */ size_t lastsent; /* Cantidad de bytes enviados en el ltimo envo. */ unsigned char *ptr; /* Puntero a los datos. */

/* Envia los datos. */

FernandoArielBeunza79156

579

Tesis de Grado en Ingeniera Informtica


sent = 0; ptr = (unsigned char *) stream; while((stream) && (sent < size)) { lastsent = write(hq, ptr + sent, size - sent); sent += lastsent; } return 1; } /* Funcin __moddrv_receive__: Enva datos por medio de la cola de mensajes. */ static int __moddrv_receive__(int hq, void *stream, size_t size) { /* Variables. */ size_t received; /* Cantidad de bytes recibidos. */ size_t lastreceive; /* Cantidad de bytes recibidos en la ltima recepcin. */ unsigned char *ptr; /* Puntero a los datos. */

/* Enva los datos. */ received = 0; ptr = (unsigned char *) stream; while((stream) && (received < size)) { lastreceive = read(hq, ptr + received, size - received); received += lastreceive; } return 1; }

C.4.4.14. Archivo modem_driver.c


/* modplc_driver.c: Implementacin de funcin principal del driver del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdio.h> #include <string.h> #include "moddrv.h"

/* Declaracin de funciones privadas. */ static char *strlwr(const char *);

/* Funcin main. */ int main(int argc, char *argv[]) { /* Variables. */ int port; int debug; moddrv_hd *hd; char *option;

/* Puerto serie utilizado. */ /* Modo depuracin. */ /* Manejador del driver del modem PLC. */ /* Opcin especificada. */

/* Carga los parmentros */ if (argc < 3) return -1;

580

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


port = atoi(argv[1]); debug = 0; if (argc > 3) { option = strlwr(strdup(argv[3])); if (!option) return -1; if (!strcmp(option, "debug")) debug = 1; } option = strlwr(strdup(argv[2])); if (!option) return -1; /* Inicializa el driver del modem PLC. */ hd = moddrv_init(port, debug); if (!hd) return 0; /* Evala la opcin solicitada. */ while(1) { /* Activa el driver. */ if (!strcmp(option, "start")) moddrv_run(hd); /* Desactiva el driver. */ else if (!strcmp(option, "stop")) moddrv_stop(hd); break; } /* Libera los recursos del driver del modem PLC. */ moddrv_release(hd); free(option); return 0; }

/* Implementacin de funciones privadas. */ /* Funcin strlwr: Convierte todas las letras de una cadena a letra minscula. */ static char *strlwr(const char *str) { /* Variables. */ char *ostr; char *instr; char *outstr;

/* Cadena de salida. */ /* Puntero a la cadena de entrada. */ /* Puntero a la cadena de salida. */

/* Convierte a minscula todas las letras de la cadena suministrada. */ if (!str) return NULL; ostr = (char *) malloc(strlen(str) + 1); if (!ostr) return NULL; instr = (char *) str; outstr = (char *) ostr; while(*instr) { *outstr = *instr; if ((*outstr >= 'A') && (*outstr <= 'Z')) { *outstr -= 'A'; *outstr += 'a'; } outstr ++; instr ++; } *outstr = *instr; return ostr;

FernandoArielBeunza79156

581

Tesis de Grado en Ingeniera Informtica


}

C.5. Especificacin del cdigo fuente del firmware del modem PLC
En esta seccin se detalla el cdigo fuente del firmware del modem PLC compuesto por los siguientes archivos:

Archivo config.h: en este archivo se definen parmetros de configuracin del modem PLC que no pueden ser modificados, tales como tamao del buffer, caracteres delimitadores de mensajes, tiempos de espera, la direccin fsica del dispositivo, etc. Archivo common.h: en este archivo se declaran primitivas con funcionalidades generales utilizadas por todas las capas. Archivo common.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo common.h. Archivo serial.h: en este archivo se declaran primitivas con funcionalidades referentes a la entrada y salida va puerto RS232. Archivo serial.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo serial.c. Archivo phy.h: en este archivo se declaran las primitivas correspondientes al manejo de los aspectos fsicos del modem PLC, inicializacin y liberacin de recursos (activacin y desactivacin de circuitos transmisor y/o receptor), y envo y recepcin de cadenas de bytes en bruto. Archivo phy.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo phy.h. Archivo mac.h: en este archivo se declaran las primitivas referentes a la subcapa de control de acceso al medio (subcapa MAC), perteneciente a la capa de enlace. Dichas primitivas brindan la capacidad de enviar y recibir mensajes por medio de un nico medio de comunicacin compartido por todos los dispositivos conectados al mismo. Archivo mac.c: en este archivo se encuentran implementadas las primitivas declaradas el el archivo mac.h. Dichas primitivas implementan, entre otras cosas, el algoritmo de control de acceso al medio. Archivo llc.h: en este archivo se declaran las primitivas referentes a la subcapa de control de lgica de enlace (subcapa LLC), perteneciente a la capa de enlace. Dichas primitivas brindan la capacidad de enviar y recibir mensajes manteniendo el control de flujo de los mismos.

582

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Archivo llc.c: en este archivo se encuentran implementadas las primitivas declaradas el el archivo llc.h. Archivo arp.h: en este archivo se declaran las primitivas referentes al protocolo de resolucin de direcciones (ARP). Dichas primitivas brindan la capacidad de identificar a cada uno de los dispositivos por medio de direcciones lgicas que pueden ser definidas independientemente de la direccin fsica preasignada. Archivo arp.c: en este archivo se encuentran implementadas las primitivas declaradas el el archivo arp.h. Archivo dl.h: en este archivo se declaran las primitivas referentes a la interfaz de la capa de enlace. Dichas primitivas renen las funcionalidades provistas por la subcapa de control de lgica de enlace (subcapa LLC) y el protocolo de resolucin de direcciones (ARP). Archivo dl.c: en este archivo se encuentran implementadas las primitivas declaradas el el archivo dl.c. Archivo net.h: en este archivo se declaran las primitivas correspondientes al manejo de la capa de red. Dichas primitivas brindan la capacidad de trabajar con mltiples redes lgicas sobre una nica red fsica. Archivo net.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo net.h. Archivo tp.h: en este archivo se declaran las primitivas correspondientes al manejo de la capa de transporte. Dichas primitivas brindan la capacidad de trabajar con grupos de difusin utilizando redes lgicas. Archivo tp.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo tp.h. Archivo sp.h: en este archivo se declaran las primitivas correspondientes al manejo de la capa de sesin. Dichas primitivas brindan la capacidad de administrar las sesiones de los grupos de difusin. Archivo sp.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo sp.h. Archivo modem.c: en este archivo se encuentra implementado el interprete de comandos del modem PLC, con el cual se interacta por medio del puerto RS232.

C.5.1. Archivo config.h


/* config.h Definicin de parmetros de configuracin. */

FernandoArielBeunza79156

583

Tesis de Grado en Ingeniera Informtica

#if !defined(__CONFIG_H__) #define __CONFIG_H__

/* Frecuencia de reloj del microcontrolador. */ #define F_CPU

11059200UL

/* Capa de fsica. */ /* Mxima cantidad de bytes que puede almacenar el buffer. */ #define PHY_PAYLOADSIZE 400 /* Cdigo de operacin de envo de trama. */ #define PHY_SNDFRMOP

0xa9

/* Cdigo de operacin de obtencin de trama capturada. */ #define PHY_GETFRMOP 0xaa /* Cdigo de operacin de captura de trama. */ #define PHY_CAPFRMOP /* Cdigo de operacin de reenvo de trama. */ #define PHY_RSDFRMOP

0xab

0xac

/* Cdigo de operacin de sensado del canal de comunicacin. */ #define PHY_SENSCHOP 0xad /* Cdigo de operacin de generacin de seal de ruido. */ #define PHY_GENNOISEOP 0xae /* Cdigo de limpieza del buffer. */ #define PHY_CRBUFFOP /* Cdigo de generacin de seal de prueba 1. */ #define PHY_TSTSIGOP1 /* Cdigo de generacin de seal de prueba 2. */ #define PHY_TSTSIGOP2 /* Cdigo de prueba de recepcin. */ #define PHY_TSTRCVOP

0xaf

0xba

0xbb

0xbc

/* Capa de enlace (subcapa MAC). */ /* Mxima cantidad de bytes que puede contener un mensaje. */ #define MAC_PAYLOADSIZE 1024 /* Caracter delimitador. */ #define MAC_DELIMITERBYTE /* Unidad de tiempo de espera. */ #define MAC_UNITTIME /* Tiempo entre mensajes. */ #define MAC_IFS /* Cantidad mxima de reintentos de transmisin. */ #define MAC_MAXRETRIES /* Cantidad mxima de errores tolerables. */ #define MAC_MAXERRORS

0x7e

20

(MAC_UNITTIME * 100)

10

100

/* Nivel de umbral de deteccin de ocupacin del canal de comunicacin. */ #define MAC_THRBUSYCHANNEL 8 /* Direccin de broadcast. */ #define MAC_BROADCASTADDR_0

0xff

584

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


#define #define #define #define #define #define #define MAC_BROADCASTADDR_1 MAC_BROADCASTADDR_2 MAC_BROADCASTADDR_3 MAC_BROADCASTADDR_4 MAC_BROADCASTADDR_5 MAC_BROADCASTADDR_6 MAC_BROADCASTADDR_7 0xff 0xff 0xff 0xff 0xff 0xff 0xff

/* Posicin de memoria de cdigo donde se almacena la direccin fsica del dispositivo. */ #define MAC_ADDRESS_ADDR 0xfff8 /* Tipos de mensaje. */ #define MAC_RTSMSG #define MAC_DATAMSG

0x01 0x02

/* Capa de enlace (subcapa LLC). */ /* Cantidad mxima de conexiones simultneas. */ #define LLC_CONNECTIONS /* Protocolos. */ #define LLC_ARPPROT #define LLC_UNUSEDPROT

0x01 0x02

/* Protocolo de resolucin de direcciones (ARP). */ /* Cantidad de direcciones lgicas por dispositivo. */ #define ARP_ADDRESS

20

/* Cantidad mxima de reintentos de solicitud de direccin fsica. */ #define ARP_MAXRETRIES 10 /* Tipos de mensaje. */ #define ARP_REQUESTMSG #define ARP_REPLYMSG /* Protocolos. */ #define ARP_UNUSEDPROT

0x01 0x02

0x01

/* Capa de red. */ /* Mxima cantidad de bytes que puede contener un mensaje. */ #define NET_PAYLOADSIZE 1500 /* Identificador de protocolo de red. */ #define NET_PROTID

0x01

/* Cantidad de interfaces fsicas presentes en el dispositivo. */ #define NET_PHYINTERFACES 1 /* Versin del protocolo de red. */ #define NET_VERSION

/* Capa de transporte. */ /* Tamao del buffer de mensajes. */ #define TP_BUFFERSIZE /* Identificador de protocolo de transporte. */ #define TP_PROTID /* Versin del protocolo de transporte. */ #define TP_VERSION

(14 * 1024)

0x01

/* Nivel de prioridad para mensajes con mxima prioridad. */ #define TP_MAXPRIOMSG 0

FernandoArielBeunza79156

585

Tesis de Grado en Ingeniera Informtica


/* Nivel de prioridad para mensajes con mxima mnima. */ #define TP_MINPRIOMSG

20

/* Capa de sesin. */ /* Versin del protocolo de transporte. */ #define SP_VERSION

/* Interfaz del modem PLC. */ /* Tamao de la lnea. */ #define MODPLC_CMDLINESIZE /* Tipos de prompt utilizados. */ #define MODPLC_INITPROMPT #define MODPLC_LAYPROMPT #define MODPLC_NORMPROMPT #define MODPLC_PARAMPROMPT /* Tipos de reset. */ #define MODPLC_NORMRESET #define MODPLC_PARAMRESET /* Capas de acceso. */ #define MODPLC_PHYSICALLAYER #define MODPLC_DATALINKLAYER #define MODPLC_SESSIONLAYER /* Cdigo de operaciones de la capa fsica. */ #define MODPLCPHY_RESET #define MODPLCPHY_SNDFRAME #define MODPLCPHY_CAPFRAME #define MODPLCPHY_GETFRAME #define MODPLCPHY_POLL #define MODPLCPHY_RSDFRAME #define MODPLCPHY_CLRBUFFER #define MODPLCPHY_SENSECHANNEL #define MODPLCPHY_GENSIGNAL #define MODPLCPHY_TSTRECEIVE #define MODPLCPHY_GETPAYLOADSIZE /* Tipos de seal. */ #define MODPLCPHY_NOISESIGNAL #define MODPLCPHY_TESTSIGNAL1 #define MODPLCPHY_TESTSIGNAL2 /* Cdigo de operaciones de la capa de enlace. */ #define MODPLCDL_RESET #define MODPLCDL_OPEN #define MODPLCDL_CLOSE #define MODPLCDL_SEND #define MODPLCDL_RECEIVE #define MODPLCDL_POLL #define MODPLCDL_GETADDRESS #define MODPLCDL_ADDLOGADDRESS #define MODPLCDL_DELLOGADDRESS #define MODPLCDL_GETPHYADDRESS #define MODPLCDL_GETPAYLOADSIZE /* Cdigo de operaciones de la capa de sesin. */ #define MODPLCSP_RESET #define MODPLCSP_PUBLISH #define MODPLCSP_SUBSCRIBE #define MODPLCSP_LEAVE #define MODPLCSP_SEND #define MODPLCSP_RECEIVE #define MODPLCSP_POLL #define MODPLCSP_GETPAYLOADSIZE

80

'#' '?' '$' '>'

"0" '$'

"1" "2" "3"

MODPLC_NORMRESET "1" "2" "3" "4" "5" "6" "7" "8" "9" "a"

0x01 0x02 0x03

MODPLC_NORMRESET "1" "2" "3" "4" "5" "6" "7" "8" "9" "a"

MODPLC_NORMRESET "1" "2" "3" "4" "5" "6" "7"

586

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

#endif

C.5.2. Archivo common.h


/* common.h: Declaracin de funciones comunes. */

#if !defined(___COMMON_H__) #define ___COMMON_H__

/* Archivos includos necesarios. */ #include "../common/common.h"

/* Definicin de funciones pblicas. */ /* Funcin wait_usecs: Espera el transcurso de una determinada microsegundos. */ void wait_usecs(long int);

#endif

C.5.3. Archivo common.c


/* common.c: Implementacin de funciones comunes. */

/* Archivos includos necesarios. */ #include "config.h" #include "../common/common.c"

/* Implementacin de funciones pblicas. */ /* Funcin wait_usecs: Espera el transcurso de una determinada microsegundos. */ void wait_usecs(long int usecs) { /* Espera con watchdog desactivado. */ if (!__wdt_status__) { while(1) { __asm nop nop nop nop nop nop nop

; ; ; ; ; ; ;

FernandoArielBeunza79156

587

Tesis de Grado en Ingeniera Informtica


__endasm; if (usecs < ((66 * F_CPU) / 11059200UL)) break; usecs -= ((66 * F_CPU) / 11059200UL); } return; } /* Espera con watchdog activado. */ while(1) { __asm push IE ; clr EA ; mov _WDTRST, #0x1e ; mov _WDTRST, #0xe1 ; pop IE ; __endasm; if (usecs < ((66 * F_CPU) / 11059200UL)) break; usecs -= ((66 * F_CPU) / 11059200UL); } }

C.5.4. Archivo serial.h


/* serial.h: Declaracin de funciones referentes a la UART. */

#include "../common/serial.h"

C.5.5. Archivo serial.c


/* serial.c: Implementacin de funciones referentes a la UART. */

#include "../common/serial.c"

C.5.6. Archivo phy.h


/* phy.h: Declaracin de funciones referentes a la capa fsica. */

#if !defined(__PHY_H__) #define __PHY_H__

/* Archivos includos necesarios. */ #include "config.h" #include <stdlib.h>

/* Definicin de funciones pblicas. */ /*

588

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Funcin phy_init: Inicializa los recursos utilizados por la capa fsica. */ void phy_init(void); /* Funcin phy_release: Libera los recursos utilizados por la capa fsica. */ void phy_release(void); /* Funcin phy_sndframe: Enva una trama. */ short int phy_sndframe(const void *, short int); /* Funcin phy_capframe: Captura una trama. */ int phy_capframe(short int); /* Funcin phy_getframe: Obtiene una trama capturada previamente. */ short int phy_getframe(void *, short int); /* Funcin phy_notify: Define una funcin manejadora de tramas capturadas. */ void phy_notify(void (*func)(void)); /* Funcin phy_poll: Verifica la captura de una trama. */ int phy_poll(void); /* Funcin phy_rsdframe: Reenva una trama. */ int phy_rsdframe(void); /* Funcin phy_clrbuffer: Limpia el buffer de captura de tramas. */ int phy_clrbuffer(void); /* Funcin phy_sensechannel: Sensa el estado del canal de comunicacin. */ int phy_sensechannel(unsigned char, long int); /* Funcin phy_gennoisesignal: Genera una seal de ruido. */ int phy_gennoisesignal(void); /* Funcin phy_tstsignal1: Genera una seal de prueba 1. */ int phy_tstsignal1(void);

FernandoArielBeunza79156

589

Tesis de Grado en Ingeniera Informtica


/* Funcin phy_tstsignal2: Genera una seal de prueba 2. */ int phy_tstsignal2(void); /* Funcin phy_tstreceive: Realiza una prueba de recepcin. */ int phy_tstreceive(void); /* Interrupcin INT0: Procesa la seal recibida. */ extern void __phy_int0__(void) __interrupt 0;

#endif

C.5.7. Archivo phy.c


/* phy.c: Implementacin de funciones referentes a la capa fsica. */

/* Archivos includos necesarios. */ #include "config.h" #include <string.h> #include <at89x52.h> #include "common.h" #include "phy.h"

/* Variables globales. */ /* Buffer de envo de un byte. */ static __data unsigned char __phy_buffbyte__; /* Funcin manejadora de tramas capturadas. */ static void (*__phy_recfun__)(void) __reentrant;

/* Declaracin de funciones privadas. */ static void __phy_waitendop__(void); static int __phy_sendbyte__(void); static int __phy_sendop__(unsigned char);

/* Implementacin de funciones pblicas. */ /* Funcin phy_init: Inicializa los recursos utilizados por la capa fsica. */ void phy_init(void) { /* Inicializa TXDAT y TXCLK. */ P1 |= 0x03; /* Inicializa RXDAT y RXCLK. */ P3 |= 0x14; /* Inicializa la funcin manejadora de tramas recibidas. */ __phy_recfun__ = NULL;

590

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


reset_watchdog(); } /* Funcin phy_release: Libera los recursos utilizados por la capa fsica. */ void phy_release(void) { reset_watchdog(); __phy_recfun__ = NULL; } /* Funcin phy_sndframe: Enva una trama. */ short int phy_sndframe(const void *dat, short int size) { /* Variables. */ register short int send; register unsigned char ea; unsigned char *ptr;

/* Cantidad de bytes enviados. */ /* Estado de las interrupciones. */ /* Puntero a la trama. */

/* Verifica que el tamao de la trama no supere el mximo permitido. */ reset_watchdog(); if (size < 1) return 0; if (size < PHY_PAYLOADSIZE) send = size; else send = PHY_PAYLOADSIZE; /* Desactiva las interruciones. */ ea = EA; EA = 0; /* Enva el cdigo de operacin. */ __phy_buffbyte__ = PHY_SNDFRMOP; if (!__phy_sendbyte__()) { __phy_waitendop__(); EA = ea; return 0; } if (__phy_buffbyte__ != PHY_SNDFRMOP) { __phy_waitendop__(); EA = ea; return 0; } /* Enva la trama. */ ptr = (unsigned char *) dat; while(send) { __phy_buffbyte__ = *((__xdata unsigned char *) ptr); if (!__phy_sendbyte__()) break; *((__xdata unsigned char *) ptr) = __phy_buffbyte__; send --; ptr ++; } /* Espera comienzo de transmisin. */ P1 |= 0x02; while(P3 & 0x04) { __asm mov _WDTRST, #0x1e mov _WDTRST, #0xe1

; ;

FernandoArielBeunza79156

591

Tesis de Grado en Ingeniera Informtica


__endasm; } /* Espera fin de transmisin. */ __phy_waitendop__(); /* Restaura el estado de las interrupciones. */ EA = ea; /* Devuelve la cantidad de bytes enviados. */ return size - send; } /* Funcin phy_capframe: Captura una trama. */ int phy_capframe(short int size) { /* Variables. */ unsigned char hsize; unsigned char lsize; register unsigned char ea;

/* Parte alta de la cantidad de bytes a capturar. */ /* Parte baja de la cantidad de bytes a capturar. */ /* Estado de las interrupciones. */

/* Desactiva las interruciones. */ ea = EA; EA = 0; /* Enva el cdigo de operacin. */ __phy_buffbyte__ = PHY_CAPFRMOP; if (!__phy_sendbyte__()) { __phy_waitendop__(); EA = ea; return 0; } if (__phy_buffbyte__ != PHY_CAPFRMOP) { __phy_waitendop__(); EA = ea; return 0; } /* Enva la cantidad de bytes a capturar. */ hsize = (unsigned char) (size >> 8); lsize = (unsigned char) (size & 0x00ff); __phy_buffbyte__ = hsize; if (!__phy_sendbyte__()) { __phy_waitendop__(); EA = ea; return 0; } if (__phy_buffbyte__ != hsize) { __phy_waitendop__(); EA = ea; return 0; } __phy_buffbyte__ = lsize; if (!__phy_sendbyte__()) { __phy_waitendop__(); EA = ea; return 0; } if (__phy_buffbyte__ != lsize) {

592

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


__phy_waitendop__(); EA = ea; return 0; } __phy_waitendop__(); /* xito. */ EA = ea; return 1; } /* Funcin phy_getframe: Obtiene una trama capturada previamente. */ short int phy_getframe(void *dat, short int size) { /* Variables. */ register short int receive; register unsigned char ea; unsigned char *ptr;

/* Cantidad de bytes recibidos. */ /* Estado de las interrupciones. */ /* Puntero a la trama. */

/* Verifica que el tamao de la trama no supere el mximo permitido. */ reset_watchdog(); if (size < 1) return 0; if (size < PHY_PAYLOADSIZE) receive = size; else receive = PHY_PAYLOADSIZE; /* Desactiva las interruciones. */ ea = EA; EA = 0; /* Enva el cdigo de operacin. */ __phy_buffbyte__ = PHY_GETFRMOP; if (!__phy_sendbyte__()) { __phy_waitendop__(); EA = ea; return 0; } if (__phy_buffbyte__ != PHY_GETFRMOP) { __phy_waitendop__(); EA = ea; return 0; } /* Obtiene la trama. */ ptr = (unsigned char *) dat; while(receive) { __phy_buffbyte__ = 0xff; if (!__phy_sendbyte__()) break; *((__xdata unsigned char *) ptr) = __phy_buffbyte__; receive --; ptr ++; } __phy_waitendop__(); /* Restaura el estado de las interrupciones. */ EA = ea; /* Devuelve la cantidad de bytes recibidos. */ return size - receive; } /*

FernandoArielBeunza79156

593

Tesis de Grado en Ingeniera Informtica


Funcin phy_notify: Define una funcin manejadora de tramas capturadas. */ void phy_notify(void (*func)(void)) { /* Define el manejador. */ __phy_recfun__ = func; /* Activa interrupcin exterior. */ cli(); IE &= 0xfe; TCON &= 0xfd; TCON |= 0x01; if (__phy_recfun__) IE |= 0x01; sei(); reset_watchdog(); } /* Funcin phy_poll: Verifica la captura de una trama. */ int phy_poll(void) { reset_watchdog(); if (P3 & 0x04) return 0; return 1; } /* Funcin phy_rsdframe: Reenva una trama. */ int phy_rsdframe(void) { /* Variables. */ register unsigned char ea;

/* Estado de las interrupciones. */

/* Desactiva las interruciones. */ ea = EA; EA = 0; /* Enva el cdigo de operacin. */ __phy_buffbyte__ = PHY_RSDFRMOP; if (!__phy_sendbyte__()) { __phy_waitendop__(); EA = ea; return 0; } if (__phy_buffbyte__ != PHY_RSDFRMOP) { __phy_waitendop__(); EA = ea; return 0; } /* Espera comienzo de transmisin. */ P1 |= 0x02; while(P3 & 0x04) { __asm mov _WDTRST, #0x1e mov _WDTRST, #0xe1 __endasm; } /* Espera fin de transmisin. */ __phy_waitendop__();

; ;

594

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Restaura el estado de las interrupciones. */ EA = ea; /* xito. */ return 1; } /* Funcin phy_clrbuffer: Limpia el buffer de captura de tramas. */ int phy_clrbuffer(void) { return __phy_sendop__(PHY_CRBUFFOP); } /* Funcin phy_sensechannel: Sensa el estado del canal de comunicacin. */ int phy_sensechannel(unsigned char thrl, long int usecs) { /* Variables. */ int busych; unsigned char thrlevel;

register unsigned char ea;

/* Indicador de canal ocupado. */ /* Nivel de umbral de deteccin de ocupacin de canal de comunicacin. */ /* Estado de las interrupciones. */

/* Desactiva las interruciones. */ ea = EA; EA = 0; /* Enva el cdigo de operacin. */ __phy_buffbyte__ = PHY_SENSCHOP; if (!__phy_sendbyte__()) { __phy_waitendop__(); EA = ea; return 0; } if (__phy_buffbyte__ != PHY_SENSCHOP) { __phy_waitendop__(); EA = ea; return 0; } /* Enva el nivel de umbral de deteccin de ocupacin de canal comunicacin. */ thrlevel = thrl; __phy_buffbyte__ = thrlevel; if (!__phy_sendbyte__()) { __phy_waitendop__(); EA = ea; return 0; } if (__phy_buffbyte__ != thrlevel) { __phy_waitendop__(); EA = ea; return 0; } /* Espera comienzo del sensado del canal de comunicacin. */ P1 |= 0x02; while(!(P3 & 0x04)) { __asm

FernandoArielBeunza79156

595

Tesis de Grado en Ingeniera Informtica


mov _WDTRST, #0x1e mov _WDTRST, #0xe1 __endasm; } wait_usecs(1000); /* Espera durante el tiempo especificado la ocupacin del canal comunicacin. */ while(P3 & 0x04) { wait_usecs(66); if (usecs < ((66 * F_CPU) / 11059200UL)) break; usecs -= ((66 * F_CPU) / 11059200UL); } busych = 2; if (P3 & 0x04) busych = 1; __phy_sendop__(0x00); /* Restaura el estado de las interrupciones. */ EA = ea; /* No se detect ocupacin del canal de comunicacin. */ return busych; } /* Funcin phy_gennoisesignal: Genera una seal de ruido. */ int phy_gennoisesignal(void) { return __phy_sendop__(PHY_GENNOISEOP); } /* Funcin phy_tstsignal1: Genera una seal de prueba 1. */ int phy_tstsignal1(void) { return __phy_sendop__(PHY_TSTSIGOP1); } /* Funcin phy_tstsignal2: Genera una seal de prueba 2. */ int phy_tstsignal2(void) { return __phy_sendop__(PHY_TSTSIGOP2); } /* Funcin phy_tstreceive: Realiza una prueba de recepcin. */ int phy_tstreceive(void) { return __phy_sendop__(PHY_TSTRCVOP); } ; ;

/* Implementacin de funciones privadas. */ /* Interrupcin INT0: Procesa la seal recibida. */ void __phy_int0__(void) __interrupt 0 { cli();

596

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


reset_watchdog(); if (__phy_recfun__) __phy_recfun__(); sei(); } /* Funcin __phy_waitendop__: Espera fin de recepcin de operacin. */ static void __phy_waitendop__(void) { /* Variables. */ unsigned short int i;

/* Contador. */

/* Espera fin de recepcin de operacin. */ while(1) { P1 |= 0x02; while(!(P3 & 0x04)) { __asm mov _WDTRST, #0x1e ; mov _WDTRST, #0xe1 ; __endasm; } for(i = 0; (i < ((50 * F_CPU) / 11059200UL)) && (P3 & 0x04); i++) { __asm mov _WDTRST, #0x1e ; mov _WDTRST, #0xe1 ; __endasm; } if (P3 & 0x04) break; } TCON &= 0xfd; } /* Funcin __phy_sendbyte__: Enva un byte del mensaje. */ static int __phy_sendbyte__(void) { /* Variables. */ register short int i;

/* Contador. */

/* Sincronizacin. */ P1 &= 0xfd; for(i = 0; i < 0x4000; i++) { __asm mov _WDTRST, #0x1e mov _WDTRST, #0xe1 __endasm; if (!(P3 & 0x04)) break; } if (P3 & 0x04) return 0; /* Envo del byte. */ __asm push push nop mov clr rlc mov setb nop

; ;

acc psw a, ___phy_buffbyte__ P1.1 a P1.0, C P1.1

; ; ; ; Carga el byte a enviar. ; Enva el bit 0. ; ; ; ;

FernandoArielBeunza79156

597

Tesis de Grado en Ingeniera Informtica


mov clr rlc mov setb nop mov clr rlc mov setb nop mov clr rlc mov setb nop mov clr rlc mov setb nop mov clr rlc mov setb nop mov clr rlc mov setb nop mov clr rlc mov setb nop mov clr rlc setb mov nop pop pop __endasm; return 1; } /* Funcin __phy_sendop__: Enva una solicitud de ejecucin de una operacin. */ static int __phy_sendop__(unsigned char op) { /* Variables. */ register unsigned char ea; C, P3.4 P1.1 a P1.0, C P1.1 C, P3.4 P1.1 a P1.0, C P1.1 C, P3.4 P1.1 a P1.0, C P1.1 C, P3.4 P1.1 a P1.0, C P1.1 C, P3.4 P1.1 a P1.0, C P1.1 C, P3.4 P1.1 a P1.0, C P1.1 C, P3.4 P1.1 a P1.0, C P1.1 C, P3.4 P1.1 a P1.0 ___phy_buffbyte__, a psw acc ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Enva el bit 1.

Enva el bit 2.

Enva el bit 3.

Enva el bit 4.

Enva el bit 5.

Enva el bit 6.

Enva el bit 7.

Fin.

/* Estado de las interrupciones. */

/* Reinicia el watchdog. */ reset_watchdog(); /* Desactiva las interruciones. */ ea = EA; EA = 0;

598

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Enva el cdigo de operacin. */ __phy_buffbyte__ = op; if (!__phy_sendbyte__()) { __phy_waitendop__(); EA = ea; return 0; } if (__phy_buffbyte__ != op) { __phy_waitendop__(); EA = ea; return 0; } __phy_waitendop__(); /* Restaura el estado de las interrupciones. */ EA = ea; /* xito. */ return 1; }

C.5.8. Archivo mac.h


/* mac.h: Declaracin de funciones referentes a la capa de enlace (subcapa MAC). */

#if !defined(__MAC_H__) #define __MAC_H__

/* Archivos includos necesarios. */ #include "config.h" #include "phy.h"

/* Definicin de tipos. */ /* Direccin fsica de dispositivo. */ typedef unsigned char mac_addr[8]; /* Encabezado del mensaje. */ typedef struct { unsigned char delimiter; mac_addr src_addr; mac_addr dest_addr; unsigned char type; unsigned char protocol; unsigned char fragment; unsigned short int size; unsigned short int total_size; } __mac_header__;

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

Comienzo de mensaje. */ Direccin de origen. */ Direccin de destino. */ Tipo de mensaje. */ Identificador de protocolo. */ Nmero de fragmento. */ Tamao del mensaje. */ Tamao total. */ Encabezado del mensaje. */

/* Definicin de constantes. */ #define MAC_HEADERSIZE #define MAC_FCSSIZE /* Direccin de broadcast. */ static __code mac_addr __mac_broadcastaddr__ = { MAC_BROADCASTADDR_0, MAC_BROADCASTADDR_1, MAC_BROADCASTADDR_2, MAC_BROADCASTADDR_3, MAC_BROADCASTADDR_4, MAC_BROADCASTADDR_5,

sizeof(__mac_header__) sizeof(unsigned short int)

FernandoArielBeunza79156

599

Tesis de Grado en Ingeniera Informtica


MAC_BROADCASTADDR_6, MAC_BROADCASTADDR_7 };

/* Definicin de funciones pblicas. */ /* Funcin mac_init: Inicializa los recursos utilizados por la subcapa MAC. */ void mac_init(void); /* Funcin mac_release: Libera los recursos utilizados por la subcapa MAC. */ void mac_release(void); /* Funcin mac_send: Enva un mensaje por medio de la subcapa MAC. */ short int mac_send(mac_addr, unsigned char, unsigned char, const void *, short int); /* Funcin mac_receive: Recibe un mensaje por medio de la subcapa MAC. */ short int mac_receive(mac_addr, unsigned char *, void *, short int); /* Funcin mac_notify: Define una funcin manejadora de mensajes recibidos. */ void mac_notify(void (*func)(mac_addr, unsigned char, void *, short int)); /* Funcin mac_poll: Verifica la llegada de un nuevo mensaje. */ int mac_poll(void); /* Funcin mac_acceptprotocol: Establece la recepcin de mensajes cuyo identificador de protocolo coincide con el especificado. */ int mac_acceptprotocol(unsigned char); /* Funcin mac_rejectprotocol: Bloquea la recepcin de mensajes cuyo identificador de protocolo coincide con el especificado. */ int mac_rejectprotocol(unsigned char); /* Funcin mac_status: Devuelve el estado del dispositivo. */ int mac_status(void); /* Funcin mac_getaddress: Devuelve la direccin fsica del dispositivo. */ void mac_getaddress(mac_addr);

#endif

600

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

C.5.9. Archivo mac.c


/* mac.c: Implementacin de funciones referentes a la capa de enlace (subcapa MAC). */

/* Archivos includos necesarios. */ #include "config.h" #include <string.h> #include "common.h" #include "phy.h" #include "mac.h"

/* Definicin de constantes. */ /* Tamao de un mensaje corto. */ #define MAC_SMSGSIZE

(2 * (MAC_HEADERSIZE + \ MAC_FCSSIZE))

/* Tamao mximo de un fragmento de mensaje. */ #define MAC_FRAGMENTSIZE

(PHY_PAYLOADSIZE - \ MAC_HEADERSIZE - MAC_FCSSIZE)

/* Direccin asignada al dispositivo. */ static __code __at (MAC_ADDRESS_ADDR) mac_addr __mac_address__;

/* Variables globales. */ /* Tamao del mensaje almacenado en el primer buffer. */ static volatile short int __mac_msg_size1__; /* Tamao del mensaje almacenado en el segundo buffer. */ static volatile short int __mac_msg_size2__; /* ltimo nmero de fragmento recibido. */ static volatile short int __mac_msg_last_frag__; /* Tamao del ltimo fragmento recibido. */ static volatile short int __mac_msg_last_frag_size__; /* Direccin de origen del mensaje recibido. */ static volatile mac_addr __mac_msg_address__; /* Contador de errores ocurridos. */ static volatile unsigned char __mac_errors__; /* Identificador de protocolo del mensaje recibido. */ static volatile unsigned char __mac_msg_protocol__; /* Valor del ltimo nmero pseudoaleatorio generado. */ static unsigned char __mac_randnum__; /* Tabla de bloqueo de protocolos. */ static volatile __mac_prot_block__[32]; /* Primer buffer de recepcin de mensajes. */ static volatile unsigned char __mac_msg_buffer1__[MAC_PAYLOADSIZE]; /* Segundo buffer de recepcin de mensajes. */ static volatile unsigned char __mac_msg_buffer2__[MAC_PAYLOADSIZE]; /* Funcin manejadora de mensajes recibidos. */ static void (*__mac_recfun__)(mac_addr, unsigned char, void *, short int)

FernandoArielBeunza79156

601

Tesis de Grado en Ingeniera Informtica


__reentrant;

/* Definicin de funciones privadas. */ static void __mac_procmsg__(void); static int __mac_sensechannel__(int); static int __mac_sendmsg__(mac_addr, unsigned char, unsigned char, unsigned char, short int, short int, const void *); static unsigned char __mac_receivemsg__(unsigned char *, mac_addr, mac_addr, unsigned char *, unsigned char *, unsigned char *, short int *, short int *);

/* Implementacin de funciones pblicas. */ /* Funcin mac_init: Inicializa los recursos utilizados por la subcapa MAC. */ void mac_init(void) { /* Variables. */ unsigned char i;

/* ndice de tabla de bloqueo de protocolos. */

/* Inicializa los recursos utilizados por la capa fsica. */ phy_init(); /* Define un manejador de mensajes recibidos por la capa fsica. */ phy_notify(__mac_procmsg__); /* Inicializa el buffer de mensajes. */ __mac_msg_size1__ = 0; __mac_msg_size2__ = 0; __mac_msg_last_frag__ = -1; __mac_msg_last_frag_size__ = 0; __mac_msg_protocol__ = 0; /* Inicializa el contador de errores. */ __mac_errors__ = 0; /* Inicializa la tabla de bloqueo de protocolos, bloqueando todos los protocolos. */ for(i = 0; i < 32; i++) __mac_prot_block__[i] = 0xff; /* Inicializa la funcin manejadora de mensajes recibidos. */ __mac_recfun__ = NULL; /* Define la semilla para la generacin del tiempo de espera pseudoaleatorio. */ __mac_randnum__ = __mac_address__[0]; /* Establece el modo captura. */ reset_watchdog(); phy_capframe(MAC_HEADERSIZE + MAC_SMSGSIZE + MAC_FCSSIZE); } /* Funcin mac_release: Libera los recursos utilizados por la subcapa MAC. */ void mac_release(void) { phy_notify(NULL); phy_release(); } /* Funcin mac_send:

602

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Enva un mensaje por medio de la subcapa MAC. */ short int mac_send(mac_addr dest_addr, unsigned char prio, const void *msg, short int msgsize) { /* Variables. */ int rsend; int result; int chstatus; short int wait; short int tosend; short int fragsize; unsigned char frag; unsigned char retries; unsigned char *ptrmsg;

unsigned char prot,

/* Indicador de reenvo. */ /* Resultado del envo. */ /* Estado del canal de comunicacin. */ /* Espera. */ /* Cantidad de bytes a enviar. */ /* Tamao del fragmento. */ /* Nmero de fragmento. */ /* Cantidad de reintentos de envo. */ /* Puntero al mensaje a enviar. */

/* Verifica que el dispositivo no se haya desactivado por sobrepasar el contador de errores. */ reset_watchdog(); if (__mac_errors__ > MAC_MAXERRORS) return 0; /* Verifica que el identificador de protocolo sea vlido. */ if (!prot) return 0; /* Verifica que el tamao del mensaje no supere el mximo permitido. */ if (msgsize > MAC_PAYLOADSIZE) return 0; /* Verifica que el transmisor no se envie un mensaje a si mismo. */ if (memccmp1(dest_addr, __mac_address__, sizeof(mac_addr))) return 0; /* Enva el mensaje. */ phy_notify(NULL); rsend = 0; fragsize = MAC_FRAGMENTSIZE; for(retries = 0; (retries < MAC_MAXRETRIES) && (msgsize); ) { /* Agrega un tiempo de espera pseudoaleatorio. */ if (retries) { __mac_randnum__ = ((__mac_randnum__ << 7) ^ (__mac_randnum__ & 0x80)) | (__mac_randnum__ >> 1); wait = __mac_randnum__; if (retries < 5) wait %= (2 << (retries + 5)); else wait %= (2 << 10); while(wait--) wait_usecs(MAC_UNITTIME); } retries ++; /* Sensa el estado del canal de comunicacin. */ chstatus = phy_sensechannel(MAC_THRBUSYCHANNEL, (MAC_HEADERSIZE + MAC_PAYLOADSIZE + MAC_FCSSIZE) * 192UL); if (chstatus == 0) { msgsize = 0; break; } if (chstatus == 2) continue; /* Introduce una espera en base a la prioridad del mensaje. */ do { wait_usecs(MAC_UNITTIME); } while(--prio);

FernandoArielBeunza79156

603

Tesis de Grado en Ingeniera Informtica


/* Sensa el estado del canal de comunicacin. */ chstatus = phy_sensechannel(MAC_THRBUSYCHANNEL, MAC_UNITTIME); if (chstatus == 0) { msgsize = 0; break; } if (chstatus == 2) continue; /* Si el mensaje es un mensaje de datos corto, se enva directamente. */ if (msgsize <= MAC_SMSGSIZE) { /* Enva el mensaje corto. */ if (rsend) result = phy_rsdframe(); else result = __mac_sendmsg__(dest_addr, MAC_DATAMSG, prot, 0, msgsize, msgsize, msg); if (result) { if (__mac_sensechannel__(1)) break; } rsend = 1; wait_usecs(MAC_IFS); __mac_errors__ ++; continue; } /* Envia mensaje de RTS para notificar a los destinatarios que se enviar un mensaje largo de datos. */ if (rsend) result = phy_rsdframe(); else result = __mac_sendmsg__(dest_addr, MAC_RTSMSG, prot, 0, fragsize, msgsize, NULL); rsend = 1; if (!result) { wait_usecs(MAC_IFS); continue; } if (!__mac_sensechannel__(1)) { __mac_errors__ ++; continue; } rsend = 0; /* Enva el mensaje largo por medio de uno o mas fragmentos. */ frag = 0; retries = 0; tosend = msgsize; ptrmsg = (unsigned char *) msg; while((tosend) && (retries < MAC_MAXRETRIES)) { /* Verifica que el fragmento no sea mas pequeo que un mensaje de datos corto. */ if (tosend < (MAC_SMSGSIZE * 2)) fragsize = MAC_SMSGSIZE * 2; /* Verifica que el fragmento no sea mas grande que la cantidad de bytes a enviar del mensaje de datos. */ if (tosend < fragsize) fragsize = tosend; /* Enva el fragmento de mensaje de datos. */ if (rsend) result = phy_rsdframe(); else result = __mac_sendmsg__(dest_addr, MAC_DATAMSG, prot, frag, fragsize, msgsize, ptrmsg); if (result)

604

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


{ if (__mac_sensechannel__(1)) { frag ++; tosend -= fragsize; ptrmsg += fragsize; rsend = 0; continue; } } wait_usecs(MAC_IFS); rsend = 1; /* Si no se pudo enviar el fragmento, disminuye el tamao del fragmento y reintenta el envo. */ if ((fragsize >> 1) > MAC_SMSGSIZE) { fragsize >>= 1; rsend = 0; } retries ++; __mac_errors__ ++; } if (!tosend) break; } if (retries >= MAC_MAXRETRIES) msgsize = 0; else __mac_errors__ = 0; /* Establece el modo captura. */ phy_clrbuffer(); phy_notify(__mac_procmsg__); phy_capframe(MAC_HEADERSIZE + MAC_SMSGSIZE + MAC_FCSSIZE); /* Devuelve el tamao del mensaje enviado. */ return msgsize; } /* Funcin mac_receive: Recibe un mensaje por medio de la subcapa MAC. */ short int mac_receive(mac_addr addr, unsigned char *prot, void *msg, short int msgsize) { /* Verifica que el dispositivo no se haya desactivado por sobrepasar el contador de errores. */ reset_watchdog(); if (__mac_errors__ > MAC_MAXERRORS) return 0; /* Espera la llegada de un mensaje. */ while(!mac_poll()); /* Devuelve el mensaje almacenado en el buffer de recepcin. */ phy_notify(NULL); *prot = __mac_msg_protocol__; if (addr) memcpy1(addr, __mac_msg_address__, sizeof(mac_addr)); if (msg) memcpy2(msg, msgsize, __mac_msg_buffer2__, __mac_msg_size2__); if (msgsize > __mac_msg_size2__) msgsize = __mac_msg_size2__; __mac_msg_size2__ = 0; phy_notify(__mac_procmsg__); /* Devuelve el tamao del mensaje recibido. */ return msgsize; } /* Funcin mac_notify: Define una funcin manejadora de mensajes recibidos. */

FernandoArielBeunza79156

605

Tesis de Grado en Ingeniera Informtica


void mac_notify(void (*func)(mac_addr, unsigned char, void *, short int)) { reset_watchdog(); if (__mac_errors__ <= MAC_MAXERRORS) __mac_recfun__ = func; } /* Funcin mac_poll: Verifica la llegada de un nuevo mensaje. */ int mac_poll(void) { reset_watchdog(); if (__mac_errors__ > MAC_MAXERRORS) return 0; return (__mac_msg_size2__ != 0); } /* Funcin mac_acceptprotocol: Establece la recepcin de mensajes cuyo identificador de protocolo coincide con el especificado. */ int mac_acceptprotocol(unsigned char prot) { /* Verifica que el dispositivo no se haya desactivado por sobrepasar el contador de errores. */ reset_watchdog(); if (__mac_errors__ > MAC_MAXERRORS) return 0; /* Verifica que el identificador de protocolo sea vlido. */ if (!prot) return 0; /* Desbloquea la recepcin de mensajes cuyo identificador de protocolo coincide con el especificado. */ __mac_prot_block__[prot >> 3] &= (0xff ^ (1 << (prot & 0x07))); return 1; } /* Funcin mac_rejectprotocol: Bloquea la recepcin de mensajes cuyo identificador de protocolo coincide con el especificado. */ int mac_rejectprotocol(unsigned char prot) { /* Verifica que el dispositivo no se haya desactivado por sobrepasar el contador de errores. */ reset_watchdog(); if (__mac_errors__ > MAC_MAXERRORS) return 0; /* Verifica que el identificador de protocolo sea vlido. */ if (!prot) return 0; /* Bloquea la recepcin de mensajes cuyo identificador de protocolo coincide con el especificado. */ __mac_prot_block__[prot >> 3] |= (1 << (prot & 0x07)); return 1; } /* Funcin mac_status: Devuelve el estado del dispositivo. */ int mac_status(void) { reset_watchdog(); return (__mac_errors__ <= MAC_MAXERRORS); } /* Funcin mac_getaddress:

606

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Devuelve la direccin fsica del dispositivo. */ void mac_getaddress(mac_addr addr) { memccpy1(addr, __mac_address__, sizeof(mac_addr)); }

/* Implementacin de funciones privadas. */ /* Funcin __mac_procmsg__: Procesa un mensaje recibido por medio de la capa fsica. */ static void __mac_procmsg__(void) { /* Variables. */ int error; int recstatus; short int msgsize; short int totalsize; unsigned char msgtype; unsigned char protocol; unsigned char fragment; mac_addr src_addr; mac_addr dest_addr;

/* Indicador de error. */ /* Resultado de la recepcin del mensaje. */ /* Tamao del mensaje recibido. */ /* Tamao total del mensaje. */ /* Tipo del mensaje recibido. */ /* Identificador de protocolo. */ /* Nmero de fragmento. */ /* Direccin de origen del mensaje. */ /* Direccin de destino del mensaje. */

/* Procesa un mensaje recibido por medio de la capa fsica. */ error = 0; while(1) { /* Recibe y desarma el mensaje recibido. */ recstatus = __mac_receivemsg__(__mac_msg_buffer1__ + __mac_msg_size1__, src_addr, dest_addr, &msgtype, &protocol, &fragment, &msgsize, &totalsize); /* Verifica la direccin destinataria. */ if (recstatus & 0x08) { msgsize = MAC_SMSGSIZE; break; } /* A cualquier mensaje que sea recibido, se responde generando una seal de ruido para ocupar el canal de comunicacin y notificar al origen que se ha recibido el mensaje. */ error = 1; phy_gennoisesignal(); wait_usecs(MAC_UNITTIME); /* Verifica si el mensaje recibido es vlido. */ if (recstatus & 0x7f) break; /* Verifica si el identificador de protocolo del mensaje se encuentra bloqueado o no. */ if (__mac_prot_block__[protocol >> 3] & (1 << (protocol & 0x07))) break; /* Verifica si el tipo de mensaje es desconocido. */ if ((msgtype != MAC_RTSMSG) && (msgtype != MAC_DATAMSG)) break; /* Sensa el estado del canal de comunicacin a la espera de alguna notificacin de error de otro receptor. */ error = 0; __mac_errors__ = 0; if (!__mac_sensechannel__(0)) break;

FernandoArielBeunza79156

607

Tesis de Grado en Ingeniera Informtica


/* Verifica si el mensaje recibido es un RTS. */ if (msgtype == MAC_RTSMSG) { __mac_msg_size1__ = 0; __mac_msg_last_frag__ = -1; __mac_msg_last_frag_size__ = 0; __mac_msg_protocol__ = 0; break; } /* Verifica si el mensaje recibido es un mensaje de datos. */ if (msgtype == MAC_DATAMSG) { if ((__mac_msg_last_frag__ >= 0) && (__mac_msg_last_frag__ == ((short int) fragment))) __mac_msg_size1__ -= __mac_msg_last_frag_size__; __mac_msg_size1__ += msgsize; __mac_msg_last_frag__ = (short int) fragment; __mac_msg_last_frag_size__ = msgsize; if (__mac_msg_size1__ < totalsize) break; } /* Acepta el mensaje recibido. */ __mac_msg_last_frag__ = -1; __mac_msg_last_frag_size__ = 0; __mac_msg_size2__ = __mac_msg_size1__; __mac_msg_size1__ = 0; __mac_msg_protocol__ = protocol; memcpy1(__mac_msg_address__, src_addr, sizeof(mac_addr)); memcpy1(__mac_msg_buffer2__, __mac_msg_buffer1__, __mac_msg_size2__); /* Invoca a la funcin manejadora de mensajes recibidos registrada. */ reset_watchdog(); if (__mac_recfun__) { __mac_recfun__(__mac_msg_address__, __mac_msg_protocol__, __mac_msg_buffer2__, __mac_msg_size2__); __mac_msg_size2__ = 0; reset_watchdog(); } msgsize = MAC_SMSGSIZE; break; } /* Verifica si se ha detectado algun error en cuyo caso prolonga la ocupacin del canal de comunicacin para notificar al origen el error. */ if (error) { wait_usecs(MAC_UNITTIME * 150); msgsize = MAC_FRAGMENTSIZE; __mac_errors__ ++; } /* Verifica que el dispositivo no se haya desactivado por sobrepasar el contador de errores. */ if (__mac_errors__ > MAC_MAXERRORS) { __mac_recfun__ = NULL; return; } /* Reestablece el modo captura. */ phy_clrbuffer(); phy_capframe(MAC_HEADERSIZE + msgsize + MAC_FCSSIZE); } /* Funcin __mac_sensechannel__: Sensa el estado del canal de comunicacin para obtener la confirmacin de

608

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


recepcin de un mensaje. */ static int __mac_sensechannel__(int wait) { /* Variables. */ int chstatus; short int i;

/* Estado del canal de comunicacin. */ /* Contador. */

/* Verifica si se solicita espera previa. */ if (wait) { if (phy_sensechannel(MAC_THRBUSYCHANNEL, 200000UL) != 2) return 0; } /* Determina el tiempo de ocupacin de canal de comunicacin para determinar la correcta recepcin de un mensaje o la recepcin errnea del mismo. */ i = 0; while(1) { chstatus = phy_sensechannel(MAC_THRBUSYCHANNEL, MAC_UNITTIME); if (chstatus != 2) break; i ++; } if ((chstatus == 0) || (i > 0)) return 0; return 1; } /* Funcin __mac_sendmsg__: Arma y enva un mensaje por medio de la capa fsica. */ static int __mac_sendmsg__(mac_addr addr, unsigned char type, unsigned char prot, unsigned char frag, short int size, short int tsize, const void *msg) { /* Variables. */ short int msgsize; /* Tamao del mensaje. */ __mac_header__ *mac_header; /* Encabezado del mensaje. */ unsigned char buffer[MAC_HEADERSIZE + MAC_FRAGMENTSIZE + MAC_FCSSIZE]; /* Buffer para el armado del mensaje. */

/* Carga el encabezado del mensaje. */ reset_watchdog(); mac_header = (__mac_header__ *) buffer; mac_header->delimiter = MAC_DELIMITERBYTE; memccpy1(mac_header->src_addr, __mac_address__, sizeof(mac_addr)); memcpy1(mac_header->dest_addr, addr, sizeof(mac_addr)); mac_header->type = type; mac_header->protocol = prot; mac_header->fragment = frag; mac_header->size = usl2b((unsigned short int) size); mac_header->total_size = usl2b((unsigned short int) tsize); /* Verifica que la direccin de destino no sea igual a la de origen. */ if (memcmp1(mac_header->dest_addr, mac_header->src_addr, sizeof(mac_addr))) return 0; /* Carga los datos del mensaje. */ if (size) { if (msg) memcpy1(buffer + MAC_HEADERSIZE, msg, size); else size = 0; }

FernandoArielBeunza79156

609

Tesis de Grado en Ingeniera Informtica


/* Carga la suma de verificacin. */ reset_watchdog(); *((unsigned short int *) (buffer + MAC_HEADERSIZE + size)) = usl2b(getfcs(buffer, MAC_HEADERSIZE + size)); /* Enva el mensaje de control. */ msgsize = MAC_HEADERSIZE + size + MAC_FCSSIZE; if (phy_sndframe(buffer, msgsize) == msgsize) return 1; return 0; } /* Funcin __mac_receivemsg__: Recibe y desarma un mensaje para ser enviado por medio de la capa fsica. */ static unsigned char __mac_receivemsg__(unsigned char *msg, mac_addr src_addr, mac_addr dest_addr, unsigned char *type, unsigned char *prot, unsigned char *frag, short int *size, short int *tsize) { /* Variables. */ short int msgsize; /* Tamao del mensaje recibido. */ short int datsize; /* Tamao de los datos del mensaje recibido. */ unsigned char msgtype; /* Tipo del mensaje recibido. */ unsigned char recstatus; /* Resultado de la recepcin del mensaje. */ __mac_header__ *mac_header; /* Encabezado del mensaje. */ unsigned char buffer[MAC_HEADERSIZE + MAC_FRAGMENTSIZE + MAC_FCSSIZE]; /* Buffer para desarmado de mensaje. */

/* Carga el encabezado del mensaje. */ recstatus = 0; reset_watchdog(); phy_getframe(buffer, MAC_HEADERSIZE + MAC_SMSGSIZE + MAC_FCSSIZE); mac_header = (__mac_header__ *) buffer; msgtype = mac_header->type; msgsize = usb2l(mac_header->size); /* Busca el delimitador del mensaje recibido. */ if (mac_header->delimiter != MAC_DELIMITERBYTE) recstatus |= 0x01; /* Verifica que el tamao del mensaje sea vlido. */ reset_watchdog(); if (msgsize > MAC_PAYLOADSIZE) { msgsize = MAC_PAYLOADSIZE; recstatus |= 0x02; } datsize = 0; if (msgtype == MAC_DATAMSG) datsize = msgsize; /* Si no se detectaron errores, lee el mensaje y verifica su validez. */ if (!recstatus) { /* Lee el mensaje recibido. */ if (datsize) phy_getframe(buffer, MAC_HEADERSIZE + datsize + MAC_FCSSIZE); /* Verifica la validez del mensaje recibido. */ reset_watchdog(); if (getfcs(buffer, MAC_HEADERSIZE + datsize) != usb2l(*((unsigned short int *) (buffer + MAC_HEADERSIZE + datsize)))) recstatus |= 0x04; }

610

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Verifica si la direccin destinataria es la de broadcast. */ reset_watchdog(); if (memccmp1(mac_header->dest_addr, __mac_broadcastaddr__, sizeof(mac_addr))) recstatus |= 0x80; else { /* Verifica la direccin destinataria. */ if (!memccmp1(mac_header->dest_addr, __mac_address__, sizeof(mac_addr))) recstatus |= 0x08; } /* Verifica si se han detectado errores. */ if (recstatus & 0x7f) return recstatus; /* Devuelve el mensaje recibido. */ if (src_addr) memcpy1(src_addr, mac_header->src_addr, sizeof(mac_addr)); if (dest_addr) memcpy1(dest_addr, mac_header->dest_addr, sizeof(mac_addr)); if (type) *type = msgtype; if (prot) *prot = mac_header->protocol; if (frag) *frag = mac_header->fragment; if (size) *size = msgsize; if (tsize) *tsize = usb2l(mac_header->total_size); if (msg && datsize) memcpy1(msg, buffer + MAC_HEADERSIZE, datsize); return recstatus; }

C.5.10. Archivo llc.h


/* llc.h: Declaracin de funciones referentes a la capa de enlace (subcapa LLC). */

#if !defined(__LLC_H__) #define __LLC_H__

/* Archivos includos necesarios. */ #include "config.h" #include "mac.h"

/* Definicin de tipos. */ /* Direccin fsica de dispositivo. */ typedef mac_addr llc_addr;

/* Definicin de constantes. */ #define LLC_FCSSIZE #define LLC_PAYLOADSIZE #define __llc_broadcastaddr__

sizeof(unsigned short int) (MAC_PAYLOADSIZE - LLC_FCSSIZE) __mac_broadcastaddr__

/* Definicin de funciones pblicas. */ /* Funcin llc_init: Inicializa los recursos utilizados por la subcapa LLC. */ void llc_init(void); /* Funcin llc_release:

FernandoArielBeunza79156

611

Tesis de Grado en Ingeniera Informtica


Libera los recursos utilizados por la subcapa LLC. */ #define llc_release()\ mac_release() /* Funcin llc_open: Abre una conexin por medio de la subcapa LLC. */ int llc_open(unsigned char); /* Funcin llc_close: Cierra una conexin por medio de la subcapa LLC. */ int llc_close(int); /* Funcin llc_send: Enva un mensaje por medio de la subcapa LLC. */ short int llc_send(int, llc_addr, unsigned char, const void *, short int); /* Funcin llc_receive: Recibe un mensaje por medio de la subcapa LLC. */ short int llc_receive(int, llc_addr, void *, short int); /* Funcin llc_notify: Define una funcin manejadora de mensajes recibidos. */ int llc_notify(int, void (*func)(llc_addr, void *, short int)); /* Funcin llc_poll: Verifica la llegada de un nuevo mensaje. */ int llc_poll(int); /* Funcin llc_status: Devuelve el estado del dispositivo. */ #define llc_status()\ mac_status() /* Funcin llc_getaddress: Devuelve la direccin fsica del dispositivo. */ #define llc_getaddress(addr)\ mac_getaddress(addr)

#endif

C.5.11. Archivo llc.c


/* llc.c: Implementacin de funciones referentes a la capa de enlace (subcapa LLC). */

/* Archivos includos necesarios. */ #include "config.h"

612

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


#include #include #include #include <string.h> "common.h" "mac.h" "llc.h"

/* Variables globales. */ /* Tabla de conexiones. */ static volatile struct llc_table { unsigned char protocol; llc_addr src_addr; short int size; unsigned char buffer[LLC_PAYLOADSIZE]; void (*recfun) (llc_addr, void *, short int) __reentrant; } __llc_table__[LLC_CONNECTIONS];

/* Protocolo. */ /* Direccin de origen. */ /* Tamao del mensaje almacenado en el buffer. */ /* Buffer de recepcin de mensajes. */

/* Funcin manejadora de mensajes recibidos.*/

/* Definicin de funciones privadas. */ static void __llc_procmsg__(mac_addr, unsigned char, void *, short int) __reentrant; static int __llc_validhandle__(int); static int __llc_findconn__(unsigned char);

/* Implementacin de funciones pblicas. */ /* Funcin llc_init: Inicializa los recursos utilizados por la subcapa LLC. */ void llc_init(void) { /* Variables. */ unsigned char con;

/* Nmero de conexin. */

/* Inicializa los recursos utilizados por la subcapa MAC. */ mac_init(); /* Define un manejador de mensajes recibidos por la subcapa MAC. */ mac_notify(__llc_procmsg__); /* Inicializa la tabla de conexiones. */ for(con = 0; con < LLC_CONNECTIONS; con++) { reset_watchdog(); __llc_table__[con].protocol = 0; } } /* Funcin llc_open: Abre una conexin por medio de la subcapa LLC. */ int llc_open(unsigned char prot) { /* Variables. */ int con;

/* Nmero de conexin. */

/* Verifica que el protocolo sea vlido. */ if ((!prot) || (prot & 0xf0)) return -1; /* Busca una conexin disponible. */

FernandoArielBeunza79156

613

Tesis de Grado en Ingeniera Informtica


for(con = 0; con < LLC_CONNECTIONS; con++) { /* Si encuentra la conexin se encuentra en uso, continua buscando. */ reset_watchdog(); if (__llc_table__[con].protocol == prot) return con; if (__llc_table__[con].protocol) continue; /* Si hay una conexin disponible, la asigna y finaliza la busqueda. */ __llc_table__[con].protocol = prot; __llc_table__[con].size = 0; __llc_table__[con].recfun = NULL; mac_acceptprotocol(__llc_table__[con].protocol); return con; } /* No se puede abrir la conexin. */ return -1; } /* Funcin llc_close: Cierra una conexin por medio de la subcapa LLC. */ int llc_close(int handle) { /* Verifica que el manejador de conexin sea vlido. */ if (!__llc_validhandle__(handle)) return 0; /* Libera la conexin. */ mac_rejectprotocol(__llc_table__[handle].protocol); __llc_table__[handle].protocol = 0; return 1; } /* Funcin llc_send: Enva un mensaje por medio de la subcapa LLC. */ short int llc_send(int handle, llc_addr dest_addr, unsigned char prio, const void *msg, short int msgsize) { /* Variables. */ short int size; /* Cantidad de bytes a enviar. */ unsigned char buffer[LLC_PAYLOADSIZE + LLC_FCSSIZE]; /* Buffer para armado de mensaje. */

/* Verifica que el manejador de conexin sea vlido. */ if (!__llc_validhandle__(handle)) return 0; /* Verifica que el tamao del mensaje no supere el mximo permitido. */ if (msgsize > LLC_PAYLOADSIZE) return 0; /* Verifica que la prioridad del mensaje sea vlida. */ if (prio > 0xfe) return 0; /* Carga los datos del mensaje. */ memcpy1(buffer, msg, msgsize); /* Carga la suma de verificacin. */ reset_watchdog(); *((unsigned short int *) (buffer + msgsize)) = usl2b(getfcs(buffer, msgsize)); /* Enva el mensaje. */ size = msgsize + LLC_FCSSIZE; if (mac_send(dest_addr, prio + 1, __llc_table__[handle].protocol, buffer, size) == size) return msgsize; return 0;

614

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


} /* Funcin llc_receive: Recibe un mensaje por medio de la subcapa LLC. */ short int llc_receive(int handle, llc_addr addr, void *msg, short int msgsize) { /* Verifica que el manejador de conexin sea vlido. */ if (!__llc_validhandle__(handle)) return 0; /* Espera la llegada de un mensaje. */ while(!llc_poll(handle)); /* Devuelve el mensaje almacenado en el buffer de recepcin. */ if (addr) memcpy1(addr, __llc_table__[handle].src_addr, sizeof(llc_addr)); if (msg) memcpy2(msg, msgsize, __llc_table__[handle].buffer, __llc_table__[handle].size); if (msgsize > __llc_table__[handle].size) msgsize = __llc_table__[handle].size; __llc_table__[handle].size = 0; mac_acceptprotocol(__llc_table__[handle].protocol); /* Devuelve el tamao del mensaje recibido. */ return msgsize; } /* Funcin llc_notify: Define una funcin manejadora de mensajes recibidos. */ int llc_notify(int handle, void (*func)(llc_addr, void *, short int)) { /* Verifica que el manejador de conexin sea vlido. */ if (!__llc_validhandle__(handle)) return -1; /* Cambia el manejador de mensajes recibidos. */ __llc_table__[handle].recfun = func; return 1; } /* Funcin llc_poll: Verifica la llegada de un nuevo mensaje. */ int llc_poll(int handle) { /* Verifica que el manejador de conexin sea vlido. */ if (!__llc_validhandle__(handle)) return -1; /* Devuelve la llegada de un nuevo mensaje. */ return (__llc_table__[handle].size != 0); }

/* Implementacin de funciones privadas. */ /* Funcin __llc_procmsg__: Procesa un mensaje recibido por medio de la subcapa MAC. */ static void __llc_procmsg__(mac_addr addr, unsigned char prot, void *msg, short int msgsize) __reentrant { /* Variables. */ int con; /* Nmero de conexin registrada. */ unsigned char *rmsg; /* Puntero al mensaje recibido. */

/* Verifica que el tamao del mensaje sea vlido. */

FernandoArielBeunza79156

615

Tesis de Grado en Ingeniera Informtica


reset_watchdog(); rmsg = (unsigned char *) msg; if (msgsize <= LLC_FCSSIZE) return; msgsize -= LLC_FCSSIZE; if (msgsize > LLC_PAYLOADSIZE) return; /* Verifica la validez del mensaje recibido. */ if (getfcs(rmsg, msgsize) != usb2l(*((unsigned short int *) (rmsg + msgsize)))) return; /* Busca la conexin destinataria. */ con = __llc_findconn__(prot); if (con == -1) return; /* Verifica si se puede aceptar el mensaje entrante. */ if (__llc_table__[con].size) return; /* Invoca a la funcin manejadora de mensajes recibidos registrada. */ reset_watchdog(); if (__llc_table__[con].recfun) { __llc_table__[con].recfun(addr, rmsg, msgsize); reset_watchdog(); return; } /* Almacena el mensaje en el buffer de recepcin. */ __llc_table__[con].size = msgsize; memcpy1(__llc_table__[con].buffer, rmsg, msgsize); memcpy1(__llc_table__[con].src_addr, addr, sizeof(llc_addr)); mac_rejectprotocol(prot); } /* Funcin __llc_validhandle__: Verifica que el manejador de conexin sea vlido. */ static int __llc_validhandle__(int handle) { reset_watchdog(); return ((handle >= 0) && (handle < LLC_CONNECTIONS)); } /* Funcin __llc_findconn__: Devuelve el manejador de la conexin solicitada. */ static int __llc_findconn__(unsigned char prot) { /* Variables. */ unsigned char con;

/* Nmero de conexin. */

/* Busca la conexin solicitada. */ for(con = 0; con < LLC_CONNECTIONS; con++) { reset_watchdog(); if (__llc_table__[con].protocol == prot) return con; } /* Conexin no encontrada. */ return -1; }

C.5.12. Archivo arp.h


/*

616

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


arp.h: Declaracin de funciones referentes al protocolo de resolucin de direcciones lgicas (ARP). */

#if !defined(__ARP_H__) #define __ARP_H__

/* Archivos includos necesarios. */ #include "config.h" #include "llc.h"

/* Definicin de tipos. */ typedef unsigned long int arp_logaddr;

/* Definicin de funciones pblicas. */ /* Funcin arp_init: Inicializa los recursos utilizados por ARP. */ void arp_init(void); /* Funcin arp_release: Libera los recursos utilizados por ARP. */ void arp_release(void); /* Funcin arp_addaddress: Agrega una nueva direccin lgica al dispositivo. */ int arp_addaddress(unsigned char, arp_logaddr); /* Funcin arp_deladdress: Elimina una direccin lgica al dispositivo. */ int arp_deladdress(unsigned char, arp_logaddr); /* Funcin arp_getaddress: Devuelve la direccin fsica asociada a la direccin lgica y protocolo. */ int arp_getaddress(unsigned char, arp_logaddr, llc_addr);

#endif

C.5.13. Archivo arp.c


/* arp.c: Implementacin de funciones referentes al protocolo de resolucin de direcciones lgicas (ARP). */

/* Archivos includos necesarios. */ #include "config.h" #include "common.h" #include <string.h> #include "llc.h"

FernandoArielBeunza79156

617

Tesis de Grado en Ingeniera Informtica


#include "arp.h"

/* Definicin de tipos. */ /* Mensaje ARP. */ typedef struct { unsigned char type; unsigned char protocol; arp_logaddr address; } __arp_msg__;

/* Tipos de mensaje. */ /* Protocolo. */ /* Direccin lgica. */

/* Variables globales. */ /* Manejador de conexin para ARP. */ static volatile int __arp_conn__; /* Tabla de direcciones. */ static volatile struct arp_table { unsigned char protocol; arp_logaddr address; } __arp_table__[ARP_ADDRESS];

/* Protocolo. */ /* Direccin. */

/* Definicin de funciones privadas. */ static int __arp_findaddr__(unsigned char, arp_logaddr); static void __arp_procmsg__(llc_addr, void *, short int) __reentrant;

/* Implementacin de funciones pblicas. */ /* Funcin arp_init: Inicializa los recursos utilizados por ARP. */ void arp_init(void) { /* Variables. */ unsigned char dir;

/* Nmero de direccin. */

/* Inicializa la tabla de direcciones. */ for(dir = 0; dir < ARP_ADDRESS; dir++) { reset_watchdog(); __arp_table__[dir].protocol = 0; } /* Inicializa los recursos utilizados por ARP. */ llc_init(); /* Abre una conexin para ARP. */ __arp_conn__ = llc_open(LLC_ARPPROT); if (__arp_conn__ < 0) return; /* Define un manejador de mensajes recibidos por la subcapa LLC. */ llc_notify(__arp_conn__, __arp_procmsg__); } /* Funcin arp_release: Libera los recursos utilizados por ARP. */ void arp_release(void) { /* Cierra la conexin utilizada para ARP. */ llc_close(__arp_conn__);

618

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Libera los recursos utilizados por la subcapa LLC. */ llc_release(); } /* Funcin arp_addaddress: Agrega una nueva direccin lgica al dispositivo. */ int arp_addaddress(unsigned char prot, arp_logaddr addr) { /* Variables. */ unsigned char dir;

/* Nmero de direccin. */

/* Verifica que el protocolo sea vlido. */ if (!prot) return 0; /* Busca un lugar libre en la tabla de direcciones. */ for(dir = 0; dir < ARP_ADDRESS; dir++) { /* Si el lugar no se encuentra libre, contina buscando. */ reset_watchdog(); if ((__arp_table__[dir].protocol == prot) && (__arp_table__[dir].address == addr)) return dir; if (__arp_table__[dir].protocol) continue; /* Agrega la direccin. */ llc_notify(__arp_conn__, NULL); __arp_table__[dir].protocol = prot; __arp_table__[dir].address = addr; llc_notify(__arp_conn__, __arp_procmsg__); return 1; } /* No se pudo agregar la direccin. */ return 0; } /* Funcin arp_deladdress: Elimina una direccin lgica al dispositivo. */ int arp_deladdress(unsigned char prot, arp_logaddr addr) { /* Variables. */ int dir;

/* Nmero de direccin. */

/* Verifica que el protocolo sea vlido. */ if (!prot) return 0; /* Verifica si existe la direccin. */ dir = __arp_findaddr__(prot, addr); if (dir == -1) return 0; /* Elimina la direccin de la tabla. */ llc_notify(__arp_conn__, NULL); __arp_table__[dir].protocol = 0; llc_notify(__arp_conn__, __arp_procmsg__); return 1; } /* Funcin arp_getaddress: Devuelve la direccin fsica asociada a la direccin lgica y protocolo. */ int arp_getaddress(unsigned char prot, arp_logaddr laddr, llc_addr paddr) { /* Variables. */ short int i; /* Contador. */

FernandoArielBeunza79156

619

Tesis de Grado en Ingeniera Informtica


int dir; int result; unsigned char retries; /* Nmero de direccin. */ /* Resultado de la solicitud de direccin fsica. */ /* Cantidad de reintentos de solicitud de direccin fsica. */ /* Direccin de origen del mensaje de respuesta. */ /* Direccin del dispositivo. */ /* Mensaje ARP. */

llc_addr src_addr; llc_addr llc_address; __arp_msg__ msg;

/* Verifica que el protocolo sea vlido. */ if (!prot) return 0; /* Verifica si la direccin lgica corresponde a la direcccin fsica del dispositivo. */ dir = __arp_findaddr__(prot, laddr); if (dir != -1) { llc_getaddress(llc_address); memcpy1(paddr, llc_address, sizeof(llc_addr)); return 1; } /* Solicita la direccin fsica asociada a la direccin lgica especificada. */ result = 0; msg.type = ARP_REQUESTMSG; if (__arp_conn__ < 0) return 0; llc_notify(__arp_conn__, NULL); for(retries = 0; retries < ARP_MAXRETRIES; retries++) { /* Lee cualquier mensaje pendiente. */ if (llc_poll(__arp_conn__)) { /* Lee el mensaje recibido. */ llc_receive(__arp_conn__, src_addr, &msg, sizeof(llc_addr)); /* Verifica la validez del mensaje recibido. */ if ((msg.type == ARP_REPLYMSG) && (msg.protocol == prot) && (msg.address == laddr)) { /* Devuelve la direccin fsica asociada a la direccin lgica.*/ memcpy(paddr, src_addr, sizeof(llc_addr)); result = 1; break; } } /* Enva el mensaje de peticin de la direccin fsica asociada a la direccin lgica. */ msg.type = ARP_REQUESTMSG; msg.protocol = prot; msg.address = laddr; if (llc_send(__arp_conn__, __llc_broadcastaddr__, 0, &msg, sizeof(__arp_msg__)) != sizeof(__arp_msg__)) break; /* Espera respuesta. */ for(i = 0; (i < 3000) && (!llc_poll(__arp_conn__)); i++) wait_usecs(1000); } /* No se pudo obtener la direccin fsica asociada a la direccin lgica. */ llc_notify(__arp_conn__, __arp_procmsg__); return result; }

620

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Implementacin de funciones privadas. */ /* Funcin __arp_findaddr__: Devuelve el nmero de direccin almacenada en la tabla. */ static int __arp_findaddr__(unsigned char prot, arp_logaddr addr) { /* Variables. */ int dir; /* Nmero de direccin. */

/* Verifica si ya existe la direccin. */ for(dir = 0; dir < ARP_ADDRESS; dir++) { if (__arp_table__[dir].protocol != prot) continue; if (__arp_table__[dir].address != addr) continue; return dir; } /* Conexin no encontrada. */ return -1; } /* Funcin __arp_procmsg__: Procesa un mensaje recibido por medio de la subcapa LLC. */ static void __arp_procmsg__(llc_addr addr, void *msg, short int msgsize) __reentrant { /* Variables. */ __arp_msg__ *amsg; /* Mensaje ARP. */

/* Carga el mensaje recibido. */ amsg = msg; /* Verifica la validez del mensaje. */ if (msgsize != sizeof(__arp_msg__)) return; /* Verifica si es una consulta. */ if (amsg->type != ARP_REQUESTMSG) return; /* Verifica si existe la direccin lgica en la tabla. */ if (__arp_findaddr__(amsg->protocol, amsg->address) == -1) return; /* Enva respuesta a consulta. */ amsg->type = ARP_REPLYMSG; llc_send(__arp_conn__, addr, 0, amsg, sizeof(__arp_msg__)); }

C.5.14. Archivo dl.h


/* dl.h: Declaracin de funciones referentes a la interfaz de la capa de enlace. */

#if !defined(__DL_H__) #define __DL_H__

/* Archivos includos necesarios. */ #include "config.h" #include "llc.h"

FernandoArielBeunza79156

621

Tesis de Grado en Ingeniera Informtica


#include "arp.h"

/* Definicin de tipos. */ /* Direccin fsica de dispositivo. */ typedef llc_addr dl_addr; /* Direccin lgica de dispositivo. */ typedef arp_logaddr dl_logaddr;

/* Definicin de constantes. */ #define DL_PAYLOADSIZE

LLC_PAYLOADSIZE

/* Definicin de funciones pblicas. */ /* Funcin dl_init: Inicializa los recursos utilizados por la capa de enlace. */ int dl_init(unsigned char); /* Funcin dl_release: Libera los recursos utilizados por la capa de enlace. */ int dl_release(unsigned char); /* Funcin dl_open: Abre una conexin por medio de la capa de enlace. */ int dl_open(unsigned char, unsigned char); /* Funcin dl_close: Cierra una conexin por medio de la capa de enlace. */ #define dl_close(hd)\ llc_close(hd) /* Funcin dl_send: Enva un mensaje por medio de la capa de enlace. */ #define dl_send(hd, paddr, prio, msg, size)\ llc_send(hd, paddr, prio, msg, size) /* Funcin dl_receive: Recibe un mensaje por medio de la capa de enlace. */ #define dl_receive(hd, paddr, msg, size)\ llc_receive(hd, paddr, msg, size) /* Funcin dl_notify: Define una funcin manejadora de mensajes recibidos. */ #define dl_notify(hd, func)\ llc_notify(hd, func) /* Funcin dl_poll: Verifica la llegada de un nuevo mensaje. */ #define dl_poll(hd)\ llc_poll(hd)

622

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin dl_getaddress: Devuelve la direccin fsica del dispositivo. */ int dl_getaddress(unsigned char, dl_addr); /* Funcin dl_addlogaddress: Agrega una nueva direccin lgica al dispositivo. */ int dl_addlogaddress(unsigned char, unsigned char, dl_logaddr); /* Funcin dl_dellogaddress: Elimina una direccin lgica al dispositivo. */ int dl_dellogaddress(unsigned char, unsigned char, dl_logaddr); /* Funcin dl_getphyaddress: Devuelve la direccin fsica asociada a la direccin lgica y protocolo. */ int dl_getphyaddress(unsigned char, unsigned char, dl_logaddr, dl_addr); /* Funcin dl_status: Devuelve el estado de la interfaz especificada del dispositivo. */ int dl_status(unsigned char); /* Funcin dl_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje. */ short int dl_getpayloadsize(unsigned char);

#endif

C.5.15. Archivo dl.c


/* dl.c: Implementacin de funciones referentes a la interfaz de la capa de enlace. */

/* Archivos includos necesarios. */ #include "config.h" #include <string.h> #include "common.h" #include "dl.h"

/* Implementacin de funciones pblicas. */ /* Funcin dl_init: Inicializa los recursos utilizados por la capa de enlace. */ int dl_init(unsigned char iface) { if (iface != 0) return -1; arp_init(); return 1; } /*

FernandoArielBeunza79156

623

Tesis de Grado en Ingeniera Informtica


Funcin dl_release: Libera los recursos utilizados por la capa de enlace. */ int dl_release(unsigned char iface) { if (iface != 0) return -1; arp_release(); return 1; } /* Funcin dl_open: Abre una conexin por medio de la capa de enlace. */ int dl_open(unsigned char iface, unsigned char prot) { if (iface != 0) return -1; return llc_open(prot + LLC_UNUSEDPROT); } /* Funcin dl_getaddress: Devuelve la direccin fsica del dispositivo. */ int dl_getaddress(unsigned char iface, dl_addr addr) { if (iface != 0) return -1; llc_getaddress(addr); return 1; } /* Funcin dl_addlogaddress: Agrega una nueva direccin lgica al dispositivo. */ int dl_addlogaddress(unsigned char iface, unsigned char prot, dl_logaddr laddr) { if (iface != 0) return -1; return arp_addaddress(ARP_UNUSEDPROT + prot, laddr); } /* Funcin dl_dellogaddress: Elimina una direccin lgica al dispositivo. */ int dl_dellogaddress(unsigned char iface, unsigned char prot, dl_logaddr laddr) { if (iface != 0) return -1; return arp_deladdress(ARP_UNUSEDPROT + prot, laddr); } /* Funcin dl_getphyaddress: Devuelve la direccin fsica asociada a la direccin lgica y protocolo. */ int dl_getphyaddress(unsigned char iface, unsigned char prot, dl_logaddr laddr, dl_addr paddr) { if (iface != 0) return -1; return arp_getaddress(ARP_UNUSEDPROT + prot, laddr, paddr); } /* Funcin dl_status: Devuelve el estado de la interfaz especificada del dispositivo. */ int dl_status(unsigned char iface) { if (iface != 0) return 0; return llc_status(); }

624

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin dl_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje. */ short int dl_getpayloadsize(unsigned char iface) { if (iface != 0) return -1; return DL_PAYLOADSIZE; }

C.5.16. Archivo net.h


/* net.h: Declaracin de funciones referentes a la capa de red. */

#if !defined(__NET_H__) #define __NET_H__

/* Archivos includos necesarios. */ #include "config.h" #include "dl.h"

/* Definicin de tipos. */ /* Identificador de mensaje. */ typedef unsigned char net_msgid; /* Identificador de nodo. */ typedef unsigned long int net_nodeid; /* Encabezado del mensaje. */ typedef struct { unsigned char version; net_msgid msgid; unsigned char protocol; unsigned short int size; } __net_header__;

/* Versin de protocolo. */ /* Identificador de mensaje. */ /* Protocolo del contenido del mensaje. */ /* Tamao del mensaje. */

/* Definicin de constantes. */ #define NET_HEADERSIZE #define NET_FCSSIZE

sizeof(__net_header__) sizeof(unsigned short int)

/* Definicin de funciones pblicas. */ /* Funcin net_init: Inicializa los recursos utilizados por la capa de red. */ void net_init(void); /* Funcin net_release: Libera los recursos utilizados por la capa de red. */ void net_release(void); /* Funcin net_send:

FernandoArielBeunza79156

625

Tesis de Grado en Ingeniera Informtica


Enva un mensaje por medio de la capa de red. */ short int net_send(net_nodeid, net_msgid, unsigned char, unsigned char, const void *, short int); /* Funcin net_receive: Recibe un mensaje por medio de la capa de red. */ short int net_receive(net_msgid *, unsigned char *, void *, short int); /* Funcin net_notify: Define una funcin manejadora de mensajes recibidos. */ void net_notify(void (*func)(net_msgid, unsigned char, void *, short int)); /* Funcin net_poll: Verifica la llegada de un nuevo mensaje. */ int net_poll(void); /* Funcin net_addaddr: Agrega una nueva direccin de nodo. */ int net_addaddr(net_nodeid); /* Funcin net_deladdr: Elimina una direccin de nodo existente. */ int net_deladdr(net_nodeid); /* Funcin net_addmsgid: Agrega un nuevo identificador de mensaje. */ int net_addmsgid(net_msgid); /* Funcin net_delmsgid: Elimina un identificador de mensaje. */ int net_delmsgid(net_msgid); /* Funcin net_status: Devuelve el estado del dispositivo. */ int net_status(void); /* Funcin net_getpayloadsize: Devuelve la cantidad mxima de bytes que debe contener un mensaje para poder ser enviado por cualquier interfaz. */ short int net_getpayloadsize(void);

#endif

C.5.17. Archivo net.c


/* net.c: Implementacin de funciones referentes a la capa de red.

626

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


*/

/* Archivos includos necesarios. */ #include "config.h" #include <string.h> #include "common.h" #include "dl.h" #include "net.h"

/* Variables globales. */ /* Tamao del mensaje almacenado en el primer buffer. */ static volatile short int __net_msg_size__; /* Identificador de mensaje recibido. */ static net_msgid __net_msg_id__; /* Protocolo del mensaje almacenado recibido. */ static volatile unsigned char __net_msg_protocol__; /* Tabla de interfaces. */ static struct net_interfacetable { int hd; unsigned char msgfilter[32]; } __net_interfacetable__[NET_PHYINTERFACES];

/* Manejador de conexin. */ /* Filtro de mensajes. */

/* Buffer de recepcin de mensajes. */ static volatile unsigned char __net_msg_buffer__[NET_PAYLOADSIZE]; /* Funcin manejadora de mensajes recibidos. */ static void (*__net_recfun__)(net_msgid, unsigned char, void *, short int) __reentrant;

/* Definicin de funciones privadas. */ static void __net_procmsg__(dl_addr, void *, short int) __reentrant; static short int __net_send__(unsigned char, dl_addr, net_msgid, unsigned char, unsigned char, short int, const void *);

/* Implementacin de funciones pblicas. */ /* Funcin net_init: Inicializa los recursos utilizados por la capa de red. */ void net_init(void) { /* Variables. */ unsigned char iface; unsigned char filter;

/* Identificador de interface. */ /* ndice de filtro de mensajes. */

/* Inicializa la tabla de ruteo. */ for(iface = 0; iface < NET_PHYINTERFACES; iface++) { /* Inicializa los recursos de la capa de enlace. */ dl_init(iface); /* Abre una conexin. */ __net_interfacetable__[iface].hd = dl_open(iface, NET_PROTID); /* Define un manejador de mensajes recibidos por la capa de enlace. */ dl_notify(__net_interfacetable__[iface].hd, __net_procmsg__); /* Inicializa el filtro de mensajes. */ for(filter = 0; filter < 32; filter++) {

FernandoArielBeunza79156

627

Tesis de Grado en Ingeniera Informtica


reset_watchdog(); __net_interfacetable__[iface].msgfilter[filter] = 0x00; } } /* Inicializa los buffers de mensajes. */ __net_msg_size__ = 0; /* Inicializa la funcin manejadora de mensajes recibidos. */ __net_recfun__ = NULL; } /* Funcin net_release: Libera los recursos utilizados por la capa de red. */ void net_release(void) { /* Variables. */ unsigned char iface;

/* Identificador de interface. */

/* Inicializa todas las interfaces fsicas disponibles. */ for(iface = 0; iface < NET_PHYINTERFACES; iface++) { /* Cierra la conexin de recepcin. */ if (__net_interfacetable__[iface].hd >= 0) dl_close(__net_interfacetable__[iface].hd); /* Libera los recursos utilizados por la capa de enlace. */ dl_release(iface); } } /* Funcin net_send: Enva un mensaje por medio de la capa de red. */ short int net_send(net_nodeid nodeid, net_msgid msgid, unsigned char prio, unsigned char prot, const void *msg, short int msgsize) { /* Variables. */ int ack; /* Indicador de envo correcto. */ unsigned char iface; /* Identificador de interface. */ dl_addr dest_addr; /* Direccin fsica de destino. */

/* Verifica que el tamao del mensaje no supere el mximo permitido. */ reset_watchdog(); if (msgsize > NET_PAYLOADSIZE) return 0; /* Enva el mensaje a travs de todas las interfaces fsicas disponibles. */ ack = 0; for(iface = 0; iface < NET_PHYINTERFACES; iface++) { /* Aplica el filtro de mensajes. */ if (!(__net_interfacetable__[iface].msgfilter[msgid >> 3] & (1 << (msgid & 0x07)))) continue; /* Obtiene la direccin fsica del destinatario del mensaje. */ if (nodeid) { if (!dl_getphyaddress(iface, NET_PROTID, (dl_logaddr) nodeid, dest_addr)) continue; } else { dest_addr[0] = 0xff;

628

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


dest_addr[1] dest_addr[2] dest_addr[3] dest_addr[4] dest_addr[5] dest_addr[6] dest_addr[7] } /* Verifica el tamao del mensaje. */ if (msgsize > (dl_getpayloadsize(iface) - NET_HEADERSIZE NET_FCSSIZE)) continue; /* Enva el fragmento del mensaje. */ if (__net_send__(iface, dest_addr, msgid, prio, prot, msgsize, msg) == msgsize) ack = 1; } /* Devuelve el tamao del mensaje enviado. */ if (ack) return msgsize; return 0; } /* Funcin net_receive: Recibe un mensaje por medio de la capa de red. */ short int net_receive(net_msgid *msgid, unsigned char *prot, void *msg, short int msgsize) { /* Variables. */ unsigned char iface; /* Identificador de interface. */ = = = = = = = 0xff; 0xff; 0xff; 0xff; 0xff; 0xff; 0xff;

/* Espera la llegada de un mensaje. */ while(!net_poll()); /* Devuelve el mensaje almacenado en el buffer de recepcin. */ if (msgid) *msgid = __net_msg_id__; if (prot) *prot = __net_msg_protocol__; if (msg) memcpy2(msg, msgsize, __net_msg_buffer__, __net_msg_size__); if (msgsize > __net_msg_size__) msgsize = __net_msg_size__; __net_msg_size__ = 0; /* Activa los manejadores de mensajes recibidos por la capa de enlace. */ for(iface = 0; iface < NET_PHYINTERFACES; iface++) dl_notify(__net_interfacetable__[iface].hd, __net_procmsg__); /* Devuelve el tamao del mensaje recibido. */ return msgsize; } /* Funcin net_notify: Define una funcin manejadora de mensajes recibidos. */ void net_notify(void (*func)(net_msgid, unsigned char, void *, short int)) { /* Define la funcin manejadora de mensajes recibidos. */ reset_watchdog(); __net_recfun__ = func; /* Invoca a la funcin manejadora de mensajes si hay un mensaje a la espera de ser recibido. */ if (!net_poll()) return; __net_recfun__(__net_msg_id__, __net_msg_protocol__, __net_msg_buffer__, __net_msg_size__); }

FernandoArielBeunza79156

629

Tesis de Grado en Ingeniera Informtica


/* Funcin net_poll: Verifica la llegada de un nuevo mensaje. */ int net_poll(void) { reset_watchdog(); return (__net_msg_size__ != 0); } /* Funcin net_addaddr: Agrega una nueva direccin de nodo. */ int net_addaddr(net_nodeid nodeid) { /* Variables. */ unsigned char iface;

/* Identificador de interface. */

/* Asigna el identificador de nodo. */ if (!nodeid) return 0; for(iface = 0; iface < NET_PHYINTERFACES; iface++) { if (!dl_addlogaddress(iface, NET_PROTID, (dl_logaddr) nodeid)) { while(1) { dl_dellogaddress(iface, NET_PROTID, (dl_logaddr) nodeid); if (!iface) return 0; iface --; } } } return 1; } /* Funcin net_deladdr: Elimina una direccin de nodo existente. */ int net_deladdr(net_nodeid nodeid) { /* Variables. */ unsigned char iface;

/* Identificador de interface. */

/* Asigna el identificador de nodo. */ if (!nodeid) return 0; for(iface = 0; iface < NET_PHYINTERFACES; iface++) { if (!dl_dellogaddress(iface, NET_PROTID, (dl_logaddr) nodeid)) break; } return 1; } /* Funcin net_addmsgid: Agrega un nuevo identificador de mensaje. */ int net_addmsgid(net_msgid msgid) { /* Variables. */ int result; unsigned char iface;

/* Resultado. */ /* Identificador de interface. */

/* Agrega el nuevo identificador de mensaje a cada una de las interfaces. */ result = 0; for(iface = 0; iface < NET_PHYINTERFACES; iface++)

630

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


{ /* Verifica que la ruta se encuentre definida. */ reset_watchdog(); if (__net_interfacetable__[iface].hd < 0) continue; /* Agrega el nuevo identificador de mensaje a la tabla de filtrado. */ result = 1; __net_interfacetable__[iface].msgfilter[msgid >> 3] |= (1 << (msgid & 0x07)); } return result; } /* Funcin net_delmsgid: Elimina un identificador de mensaje. */ int net_delmsgid(net_msgid msgid) { /* Variables. */ int result; unsigned char iface;

/* Resultado. */ /* Identificador de interface. */

/* Agrega el nuevo identificador de mensaje a cada una de las interfaces. */ result = 0; for(iface = 0; iface < NET_PHYINTERFACES; iface++) { /* Verifica que la ruta se encuentre definida. */ reset_watchdog(); if (__net_interfacetable__[iface].hd < 0) continue; /* Elimina el identificador de mensaje a la tabla de filtrado. */ result = 1; __net_interfacetable__[iface].msgfilter[msgid >> 3] &= (0xff ^ (1 << (msgid & 0x07))); } return result; } /* Funcin net_status: Devuelve el estado del dispositivo. */ int net_status(void) { /* Variables. */ unsigned char iface;

/* Identificador de interface. */

/* Verifica el estado de cada interfaz fsica. */ for(iface = 0; iface < NET_PHYINTERFACES; iface++) if (dl_status(iface)) return 1; return 0; } /* Funcin net_getpayloadsize: Devuelve la cantidad mxima de bytes que debe contener un mensaje para poder ser enviado por cualquier interfaz. */ short int net_getpayloadsize(void) { /* Variables. */ short int payload; unsigned char iface;

/* Capacidad mxima del mensaje. */ /* Identificador de interface. */

/* Obtiene la interfaz con la menor capacidad mxima de bytes que puede contener un mensaje. */

FernandoArielBeunza79156

631

Tesis de Grado en Ingeniera Informtica


payload = NET_PAYLOADSIZE; for(iface = 0; iface < NET_PHYINTERFACES; iface++) { if (payload > dl_getpayloadsize(iface)) payload = dl_getpayloadsize(iface); } return payload - NET_HEADERSIZE - NET_FCSSIZE; }

/* Implementacin de funciones privadas. */ /* Funcin __net_procmsg__: Procesa un mensaje recibido por medio de la capa de enlace. */ static void __net_procmsg__(dl_addr addr, void *msg, short int msgsize) __reentrant { /* Variables. */ short int size; /* Tamao del mensaje recibido. */ unsigned char iface; /* Identificador de interface. */ unsigned char msgid; /* Identificador de mensaje. */ unsigned char filter; /* Filto de mensajes. */ unsigned char version; /* Versin del protocolo de red. */ unsigned char protocol; /* Protocolo del mensaje. */ unsigned char *rmsg; /* Puntero al mensaje recibido. */ __net_header__ *net_header; /* Encabezado del mensaje. */

/* Inicia la carga del encabezado del mensaje. */ reset_watchdog(); rmsg = (unsigned char *) msg; net_header = (__net_header__ *) msg; /* Verifica la versin del protocolo de red del mensaje recibido */ version = net_header->version; if (version > NET_VERSION) return; /* Obtiene la cantidad de bytes que contiene el fragmento. */ msgsize -= (NET_HEADERSIZE + NET_FCSSIZE); /* Verifica la validez del mensaje recibido. */ reset_watchdog(); if (getfcs(rmsg, NET_HEADERSIZE + msgsize) != usb2l(*((unsigned short int *) (rmsg + NET_HEADERSIZE + msgsize)))) return; /* Carga el resto del encabezado del mensaje. */ msgid = net_header->msgid; protocol = net_header->protocol; size = (short int) usb2l(net_header->size); /* Aplica el filtro de mensajes. */ filter = 0; for(iface = 0; iface < NET_PHYINTERFACES; iface++) filter |= __net_interfacetable__[iface].msgfilter[msgid >> 3]; if (!(filter & (1 << (msgid & 0x07)))) return; /* Verifica que el buffer no se encuentre lleno. */ if (__net_msg_size__) return; /* Invoca a la funcin manejadora de mensajes recibidos registrada. */ reset_watchdog(); rmsg += NET_HEADERSIZE; if (__net_recfun__) { __net_recfun__(msgid, protocol, rmsg, size); reset_watchdog(); return; }

632

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Almacena el mensaje recibido. */ __net_msg_id__ = msgid; __net_msg_size__ = size; __net_msg_protocol__ = protocol; memcpy1(__net_msg_buffer__, rmsg, __net_msg_size__); addr[0] = 0x00; /* Desactiva los manejadores de mensajes recibidos por la capa de enlace. */ for(iface = 0; iface < NET_PHYINTERFACES; iface++) dl_notify(__net_interfacetable__[iface].hd, NULL); } /* Funcin __net_send__: Enva un mensaje por medio de la capa de red. */ static short int __net_send__(unsigned char iface, dl_addr addr, net_msgid msgid, unsigned char prio, unsigned char prot, short int msgsize, const void *msg) { /* Variables. */ short int size; /* Cantidad de bytes a enviar. */ __net_header__ *net_header; /* Encabezado del mensaje. */ unsigned char buffer[NET_HEADERSIZE + NET_PAYLOADSIZE + NET_FCSSIZE]; /* Buffer para armado de mensaje. */

/* Carga el encabezado del mensaje. */ reset_watchdog(); net_header = (__net_header__ *) buffer; net_header->version = NET_VERSION; net_header->msgid = msgid; net_header->protocol = prot; net_header->size = usl2b((unsigned short int) msgsize); /* Carga los datos del mensaje. */ memcpy1(buffer + NET_HEADERSIZE, msg, msgsize); /* Carga la suma de verificacin. */ reset_watchdog(); *((unsigned short int *) (buffer + NET_HEADERSIZE + msgsize)) = usl2b(getfcs(buffer, NET_HEADERSIZE + msgsize)); /* Enva el mensaje. */ size = NET_HEADERSIZE + msgsize + NET_FCSSIZE; if (dl_send(__net_interfacetable__[iface].hd, addr, prio, buffer, size) == size) return msgsize; return 0; }

C.5.18. Archivo tp.h


/* tp.h: Declaracin de funciones referentes a la capa de transporte. */

#if !defined(__TP_H__) #define __TP_H__

/* Archivos includos necesarios. */

FernandoArielBeunza79156

633

Tesis de Grado en Ingeniera Informtica


#include "config.h" #include "net.h"

/* Definicin de tipos. */ /* Identificador de grupo. */ typedef unsigned char tp_grpid; /* Encabezado del mensaje. */ typedef struct { unsigned char version; char sequence; } __tp_header__;

/* Versin del protocolo. */ /* Nmero de secuencia del mensaje. */

/* Definicin de constantes. */ #define TP_HEADERSIZE #define TP_PAYLOADSIZE

sizeof(__tp_header__) (NET_PAYLOADSIZE - TP_HEADERSIZE)

/* Definicin de funciones pblicas. */ /* Funcin tp_init: Inicializa los recursos utilizados por la capa de transporte. */ void tp_init(void); /* Funcin tp_release: Libera los recursos utilizados por la capa de transporte. */ void tp_release(void); /* Funcin tp_send: Enva un mensaje por medio de la capa de transporte. */ short int tp_send(tp_grpid, unsigned char, const void *, short int); /* Funcin tp_receive: Recibe un mensaje por medio de la capa de transporte. */ short int tp_receive(tp_grpid *, void *, short int); /* Funcin tp_notify: Define una funcin manejadora de mensajes recibidos. */ void tp_notify(void (*func)(tp_grpid, void *, short int)); /* Funcin tp_poll: Verifica la llegada de un nuevo mensaje. */ int tp_poll(void); /* Funcin tp_setownergrp: Establece el nodo como propietario del grupo especificado. */ int tp_setownergrp(tp_grpid); /* Funcin tp_setmembergrp: Establece el nodo como miembro del grupo especificado. */

634

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


int tp_setmembergrp(tp_grpid); /* Funcin tp_leavegrp: Desvincula el nodo del grupo especificado. */ int tp_leavegrp(tp_grpid); /* Funcin tp_status: Devuelve el estado del dispositivo. */ int tp_status(void); /* Funcin tp_getpayloadsize: Devuelve la cantidad mxima de bytes que debe contener un mensaje para poder ser enviado por cualquier interfaz. */ short int tp_getpayloadsize(void);

#endif

C.5.19. Archivo tp.c


/* tp.c: Implementacin de funciones referentes a la capa de transporte. */

/* Archivos includos necesarios. */ #include "config.h" #include <string.h> #include "common.h" #include "net.h" #include "tp.h"

/* Definicin de tipos. */ /* Tipo cola de mensajes. */ typedef struct { void *next; tp_grpid grpid; short int size; } __tp_msg_fifo__;

/* Puntero al siguiente mensaje. */ /* Identificador de grupo. */ /* Tamao del mensaje. */

/* Variables globales. */ /* Estado del nodo. */ static volatile unsigned char __tp_status__; /* Tabla de grupos del cual el nodo es propietario. */ static volatile unsigned char __tp_ownergrptable__[32]; /* Buffer de recepcin de mensajes. */ static volatile unsigned char __tp_msg_buffer__[TP_BUFFERSIZE]; /* Puntero al mensaje a despachar. */ static volatile __tp_msg_fifo__ *__tp_msg__; /* Tabla de nmeros de secuencia. */ static volatile char __tp_sectable__[256];

FernandoArielBeunza79156

635

Tesis de Grado en Ingeniera Informtica


/* Funcin manejadora de mensajes recibidos. */ static void (*__tp_recfun__)(tp_grpid, void *, short int) __reentrant;

/* Definicin de funciones privadas. */ static void __tp_procmsg__(net_msgid, unsigned char, void *, short int) __reentrant; static short int __tp_send__(net_nodeid, net_msgid, unsigned char, char, short int, const void *);

/* Implementacin de funciones pblicas. */ /* Funcin tp_init: Inicializa los recursos utilizados por la capa de transporte. */ void tp_init(void) { /* Variables. */ unsigned char i;

/* Contador. */

/* Inicializa los recursos utilizados por la capa de red. */ net_init(); /* Define un manejador de mensajes recibidos por la capa de red. */ net_notify(__tp_procmsg__); /* Inicializa la tabla de grupos. */ for(i = 0; i < 32; i++) { reset_watchdog(); __tp_ownergrptable__[i] = 0x00; } /* Inicializa los buffers de mensajes. */ __tp_msg__ = NULL; /* Inicializa la funcin manejadora de mensajes recibidos. */ __tp_recfun__ = NULL; /* Inicializa el nodo como operativo. */ __tp_status__ = 1; } /* Funcin tp_release: Libera los recursos utilizados por la capa de transporte. */ void tp_release(void) { net_notify(NULL); net_release(); } /* Funcin tp_send: Enva un mensaje por medio de la capa de transporte. */ short int tp_send(tp_grpid grpid, unsigned char nosec, const void *msg, short int msgsize) { /* Verifica que el tamao del mensaje no supere el mximo permitido. */ reset_watchdog(); if (msgsize > tp_getpayloadsize()) return 0; /* Verifica si el nodo es propietario del grupo. */ if (!(__tp_ownergrptable__[grpid >> 3] & (1 << (grpid & 0x07)))) return 0;

636

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Enva el mensaje. */ if (nosec) return __tp_send__(0, grpid, TP_MAXPRIOMSG, -1, msgsize, msg); if (__tp_send__(0, grpid, TP_MINPRIOMSG, __tp_sectable__[grpid], msgsize, msg) == msgsize) { __tp_sectable__[grpid] ++; if (__tp_sectable__[grpid] < 0) __tp_sectable__[grpid] = 0; return msgsize; } return 0; } /* Funcin tp_receive: Recibe un mensaje por medio de la capa de transporte. */ short int tp_receive(tp_grpid *grpid, void *msg, short int msgsize) { /* Espera la llegada de un mensaje. */ while(!tp_poll()); /* Devuelve el mensaje almacenado en el buffer de recepcin. */ if (grpid) *grpid = __tp_msg__->grpid; if (msg) memcpy2(msg, msgsize, __tp_msg__ + sizeof(__tp_msg_fifo__), __tp_msg__->size); if (msgsize > __tp_msg__->size) msgsize = __tp_msg__->size; __tp_msg__ = __tp_msg__->next; /* Activa el manejador de mensajes recibidos por la capa de red. */ net_notify(__tp_procmsg__); /* Devuelve el tamao del mensaje recibido. */ return msgsize; } /* Funcin tp_notify: Define una funcin manejadora de mensajes recibidos. */ void tp_notify(void (*func)(tp_grpid, void *, short int)) { /* Define la funcin manejadora de mensajes recibidos. */ reset_watchdog(); __tp_recfun__ = func; /* Invoca a la funcin manejadora de mensajes si hay un mensaje a la espera de ser recibido. */ while(tp_poll() && __tp_recfun__) { __tp_recfun__(__tp_msg__->grpid, __tp_msg__ + sizeof(__tp_msg_fifo__), __tp_msg__->size); __tp_msg__ = __tp_msg__->next; } } /* Funcin tp_poll: Verifica la llegada de un nuevo mensaje. */ int tp_poll(void) { reset_watchdog(); return (__tp_msg__ != NULL); } /* Funcin tp_setownergrp: Establece el nodo como propietario del grupo especificado. */ int tp_setownergrp(tp_grpid grpid)

FernandoArielBeunza79156

637

Tesis de Grado en Ingeniera Informtica


{ /* Agrega la direccin. */ if (!net_addaddr(((net_nodeid) grpid) | 0x0100)) return 0; /* Agrega el identificador de mensaje. */ if (!net_addmsgid((net_msgid) grpid)) net_deladdr(((net_nodeid) grpid) | 0x0100); /* Agrega el grupo a la tabla. */ __tp_ownergrptable__[grpid >> 3] |= (1 << (grpid & 0x07)); /* Inicializa el nmero de secuencia de mensaje. */ __tp_sectable__[grpid] = 0; return 1; } /* Funcin tp_setmembergrp: Establece el nodo como miembro del grupo especificado. */ int tp_setmembergrp(tp_grpid grpid) { /* Verifica que el nodo no sea propietario y miembro simultneamente. */ if (__tp_ownergrptable__[grpid >> 3] & (1 << (grpid & 0x07))) return 0; /* Inicializa el nmero de secuencia de mensaje. */ __tp_sectable__[grpid] = -1; /* Agrega el identificador de mensaje. */ return net_addmsgid((net_msgid) grpid); } /* Funcin tp_leavegrp: Desvincula el nodo del grupo especificado. */ int tp_leavegrp(tp_grpid grpid) { /* Elimina la direccin. */ net_deladdr(((net_nodeid) grpid) | 0x0100); /* Elimina el identificador de mensaje. */ if (!net_delmsgid((net_msgid) grpid)) return 0; /* Elimina el grupo a la tabla. */ __tp_ownergrptable__[grpid >> 3] &= (0xff ^ (1 << (grpid & 0x07))); return 1; } /* Funcin tp_status: Devuelve el estado del dispositivo. */ int tp_status(void) { reset_watchdog(); if (!__tp_status__) return 0; return net_status(); } /* Funcin tp_getpayloadsize: Devuelve la cantidad mxima de bytes que debe contener un mensaje para poder ser enviado por cualquier interfaz. */ short int tp_getpayloadsize(void) { return net_getpayloadsize() - TP_HEADERSIZE; }

638

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

/* Implementacin de funciones privadas. */ /* Funcin __tp_procmsg__: Procesa un mensaje recibido por medio de la capa de red. */ static void __tp_procmsg__(net_msgid msgid, unsigned char prot, void *msg, short int msgsize) __reentrant { /* Variables. */ char sequence; /* Nmero de secuencia del mensaje. */ unsigned char *rmsg; /* Puntero al mensaje recibido. */ __tp_header__ *tp_header; /* Encabezado del mensaje. */ __tp_msg_fifo__ *ptrmsg; /* Puntero al mensaje. */

/* Inicia la carga del encabezado del mensaje. */ reset_watchdog(); rmsg = (unsigned char *) msg; tp_header = (__tp_header__ *) msg; /* Verifica el identificador de protocolo. */ if (prot > TP_PROTID) return; /* Verifica la versin del protocolo de red del mensaje recibido */ if (tp_header->version > TP_VERSION) return; /* Obtiene la cantidad de bytes que contiene el mensage recibido. */ msgsize -= TP_HEADERSIZE; if (msgsize > TP_PAYLOADSIZE) return; /* Carga el resto del encabezado del mensaje. */ sequence = tp_header->sequence; /* Verifica la validez del nmero de sencuencia del mensaje recibido. */ if ((sequence >= 0) && (__tp_sectable__[msgid] >= 0)) { /* Si el nmero de secuencia recibido supera al ltimo recibido significa que se perdieron mensajes. */ if (sequence > (__tp_sectable__[msgid] + 1)) { __tp_status__ = 0; net_notify(NULL); return; } /* Si el nmero de secuencia recibido es menor al ltimo recibido significa que el mensaje ya fue recibido con anterioridad. */ if (sequence <= __tp_sectable__[msgid]) return; } /* Busca un lugar en el buffer para almacenar el mensaje recibido. */ if (__tp_msg__) { ptrmsg = __tp_msg__; while(ptrmsg->next) { reset_watchdog(); ptrmsg = ptrmsg->next; } ptrmsg->next = ((unsigned char *) ptrmsg) + sizeof(__tp_msg_fifo__) + ptrmsg->size; if ((((unsigned char *) ptrmsg->next) + sizeof(__tp_msg_fifo__) + msgsize) >= (__tp_msg_buffer__ + TP_BUFFERSIZE)) { ptrmsg->next = __tp_msg_buffer__; if ((((unsigned char *) ptrmsg->next) + sizeof(__tp_msg_fifo__) + msgsize) >= ((unsigned char *) __tp_msg__))

FernandoArielBeunza79156

639

Tesis de Grado en Ingeniera Informtica


{ ptrmsg->next = NULL; return; } } ptrmsg = ptrmsg->next; } else { __tp_msg__ = (__tp_msg_fifo__ *) __tp_msg_buffer__; ptrmsg = __tp_msg__; } /* Almacena el mensaje recibido. */ rmsg += TP_HEADERSIZE; ptrmsg->next = NULL; ptrmsg->grpid = (tp_grpid) msgid; ptrmsg->size = msgsize; memcpy1(ptrmsg + sizeof(__tp_msg_fifo__), rmsg, msgsize); if (sequence >= 0) __tp_sectable__[msgid] = sequence; /* Invoca a la funcin manejadora de mensajes recibidos registrada. */ reset_watchdog(); if (__tp_recfun__) { __tp_recfun__(__tp_msg__->grpid, ptrmsg + sizeof(__tp_msg_fifo__), __tp_msg__->size); reset_watchdog(); __tp_msg__ = __tp_msg__->next; return; } } /* Funcin __tp_send__: Enva un mensaje por medio de la capa de transporte. */ static short int __tp_send__(net_nodeid nodeid, net_msgid msgid, unsigned char prio, char sec, short int msgsize, const void *msg) { /* Variables. */ short int size; /* Cantidad de bytes a enviar. */ __tp_header__ *tp_header; /* Encabezado del mensaje. */ unsigned char buffer[TP_HEADERSIZE + TP_PAYLOADSIZE]; /* Buffer para armado de mensaje. */

/* Carga el encabezado del mensaje. */ reset_watchdog(); tp_header = (__tp_header__ *) buffer; tp_header->version = TP_VERSION; tp_header->sequence = sec; /* Carga los datos del mensaje. */ memcpy1(buffer + TP_HEADERSIZE, msg, msgsize); /* Enva el mensaje. */ size = TP_HEADERSIZE + msgsize; if (net_send(nodeid, msgid, prio, TP_PROTID, buffer, size) == size) return msgsize; return 0; }

C.5.20. Archivo sp.h


/*

640

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


sp.h: Declaracin de funciones referentes a la capa de sesin. */

#if !defined(__SP_H__) #define __SP_H__

/* Archivos includos necesarios. */ #include "config.h" #include "tp.h"

/* Definicin de tipos. */ /* Identificador de grupo. */ typedef unsigned char sp_grpid; /* Encabezado del mensaje. */ typedef struct { unsigned char version; } __sp_header__;

/* Versin del protocolo. */

/* Definicin de constantes. */ #define SP_HEADERSIZE #define SP_PAYLOADSIZE

sizeof(__sp_header__) (TP_PAYLOADSIZE - SP_HEADERSIZE)

/* Definicin de funciones pblicas. */ /* Funcin sp_init: Inicializa los recursos utilizados por la capa de sesin. */ void sp_init(void); /* Funcin sp_release: Libera los recursos utilizados por la capa de sesin. */ void sp_release(void); /* Funcin sp_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ int sp_publish(sp_grpid); /* Funcin sp_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ int sp_subscribe(sp_grpid); /* Funcin sp_leave: Desvincula el dispositivo del grupo de difusin especificado. */ int sp_leave(sp_grpid); /* Funcin sp_send: Enva un mensaje por medio de la capa de sesin. */ short int sp_send(sp_grpid, unsigned char, const void *, short int); /* Funcin sp_receive:

FernandoArielBeunza79156

641

Tesis de Grado en Ingeniera Informtica


Recibe un mensaje por medio de la capa de sesin. */ short int sp_receive(sp_grpid *, void *, short int); /* Funcin sp_notify: Define una funcin manejadora de mensajes recibidos. */ void sp_notify(void (*func)(sp_grpid, void *, short int)); /* Funcin sp_poll: Verifica la llegada de un nuevo mensaje. */ int sp_poll(void); /* Funcin sp_status: Devuelve el estado del dispositivo. */ int sp_status(void); /* Funcin sp_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje. */ short int sp_getpayloadsize(void);

#endif

C.5.21. Archivo sp.c


/* sp.c: Implementacin de funciones referentes a la capa de sesin. */

/* Archivos includos necesarios. */ #include "config.h" #include "common.h" #include <string.h> #include "tp.h" #include "sp.h"

/* Variables globales. */ /* Tamao del mensaje almacenado en el buffer. */ static volatile short int __sp_msg_size__; /* Identificador de grupo al que pertenece el mensaje recibido. */ static sp_grpid __sp_msg_grpid__; /* Buffer de recepcin de mensajes. */ static volatile unsigned char __sp_msg_buffer__[SP_PAYLOADSIZE]; /* Funcin manejadora de mensajes recibidos. */ static void (*__sp_recfun__)(sp_grpid, void *, short int) __reentrant;

/* Definicin de funciones privadas. */ static void __sp_procmsg__(tp_grpid, void *, short int) __reentrant;

/* Implementacin de funciones pblicas. */

642

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin sp_init: Inicializa los recursos utilizados por la capa de sesin. */ void sp_init(void) { /* Inicializa los recursos utilizados por la capa de transporte. */ tp_init(); /* Define un manejador de mensajes recibidos por la capa de transporte. */ tp_notify(__sp_procmsg__); /* Inicializa los buffers de mensajes. */ __sp_msg_size__ = 0; /* Inicializa la funcin manejadora de mensajes recibidos. */ __sp_recfun__ = NULL; } /* Funcin sp_release: Libera los recursos utilizados por la capa de sesin. */ void sp_release(void) { tp_notify(NULL); tp_release(); } /* Funcin sp_publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ int sp_publish(sp_grpid grpid) { return tp_setownergrp(grpid); } /* Funcin sp_subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ int sp_subscribe(sp_grpid grpid) { return tp_setmembergrp(grpid); } /* Funcin sp_leave: Desvincula el dispositivo del grupo de difusin especificado. */ int sp_leave(sp_grpid grpid) { return tp_leavegrp(grpid); } /* Funcin sp_send: Enva un mensaje por medio de la capa de sesin. */ short int sp_send(sp_grpid grpid, unsigned char nosec, const void *msg, short int msgsize) { /* Variables. */ short int size; /* Cantidad de bytes a enviar. */ __sp_header__ *sp_header; /* Encabezado del mensaje. */ unsigned char buffer[SP_HEADERSIZE + SP_PAYLOADSIZE]; /* Buffer para armado de mensaje. */

FernandoArielBeunza79156

643

Tesis de Grado en Ingeniera Informtica


/* Verifica que el tamao del mensaje no supere el mximo permitido. */ reset_watchdog(); if (msgsize > sp_getpayloadsize()) return 0; /* Carga el encabezado del mensaje. */ sp_header = (__sp_header__ *) buffer; sp_header->version = SP_VERSION; /* Carga los datos del mensaje. */ memcpy1(buffer + SP_HEADERSIZE, msg, msgsize); /* Enva el mensaje. */ size = SP_HEADERSIZE + msgsize; if (tp_send(grpid, nosec, buffer, size) == size) return msgsize; return 0; } /* Funcin sp_receive: Recibe un mensaje por medio de la capa de sesin. */ short int sp_receive(sp_grpid *grpid, void *msg, short int msgsize) { /* Espera la llegada de un mensaje. */ while(!sp_poll()); /* Devuelve el mensaje almacenado en el buffer de recepcin. */ if (grpid) *grpid = __sp_msg_grpid__; if (msg) memcpy2(msg, msgsize, __sp_msg_buffer__, __sp_msg_size__); if (msgsize > __sp_msg_size__) msgsize = __sp_msg_size__; __sp_msg_size__ = 0; /* Activa el manejador de mensajes recibidos por la capa de transporte. */ tp_notify(__sp_procmsg__); /* Devuelve el tamao del mensaje recibido. */ return msgsize; } /* Funcin sp_notify: Define una funcin manejadora de mensajes recibidos. */ void sp_notify(void (*func)(sp_grpid, void *, short int)) { /* Define la funcin manejadora de mensajes recibidos. */ reset_watchdog(); __sp_recfun__ = func; /* Invoca a la funcin manejadora de mensajes si hay un mensaje a la espera de ser recibido. */ if (!sp_poll()) return; __sp_recfun__(__sp_msg_grpid__, __sp_msg_buffer__, __sp_msg_size__); } /* Funcin sp_poll: Verifica la llegada de un nuevo mensaje. */ int sp_poll(void) { reset_watchdog(); return (__sp_msg_size__ != 0); } /* Funcin sp_status: Devuelve el estado del dispositivo. */ int sp_status(void) {

644

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


return tp_status(); } /* Funcin sp_getpayloadsize: Devuelve la cantidad mxima de bytes que puede contener un mensaje. */ short int sp_getpayloadsize(void) { return tp_getpayloadsize() - SP_HEADERSIZE; }

/* Implementacin de funciones privadas. */ /* Funcin __sp_procmsg__: Procesa un mensaje recibido por medio de la capa de transporte. */ static void __sp_procmsg__(tp_grpid grpid, void *msg, short int msgsize) __reentrant { /* Variables. */ unsigned char *rmsg; /* Puntero al mensaje recibido. */ __sp_header__ *sp_header; /* Encabezado del mensaje. */

/* Inicia la carga del encabezado del mensaje. */ reset_watchdog(); rmsg = (unsigned char *) msg; sp_header = (__sp_header__ *) msg; /* Verifica la versin del protocolo de red del mensaje recibido */ if (sp_header->version > SP_VERSION) return; /* Obtiene la cantidad de bytes que contiene el mensage recibido. */ msgsize -= SP_HEADERSIZE; if (msgsize > SP_PAYLOADSIZE) return; /* Verifica que el buffer no se encuentre lleno. */ if (__sp_msg_size__) return; /* Invoca a la funcin manejadora de mensajes recibidos registrada. */ reset_watchdog(); rmsg += SP_HEADERSIZE; if (__sp_recfun__) { __sp_recfun__(grpid, rmsg, msgsize); reset_watchdog(); return; } /* Almacena el mensaje recibido. */ __sp_msg_size__ = msgsize; __sp_msg_grpid__ = (sp_grpid) grpid; memcpy1(__sp_msg_buffer__, rmsg, __sp_msg_size__); /* Desactiva el manejador de mensajes recibidos por la capa de transporte. */ tp_notify(NULL); }

C.5.22. Archivo modem.c


/* modem.c: Firmware del modem PLC. */

FernandoArielBeunza79156

645

Tesis de Grado en Ingeniera Informtica

/* Archivos includos necesarios. */ #include <stdio.h> #include <string.h> #include <at89x52.h> #include "serial.h" #include "common.h" #include "phy.h" #include "dl.h" #include "sp.h"

/* Declaracin de funciones privadas. */ static void modem_phymode(void); static void modem_dlmode(void); static void modem_spmode(void); static void modem_outputbyte(unsigned char); static void modem_outputint(short int); static void modem_outputstream(const void *, short int); static void modem_inputstream(void *, short int);

/* Funcin main: Funcin principal. */ void main(void) { /* Variables. */ char line[MODPLC_CMDLINESIZE];

/* Lnea de comandos. */

/* Inicializacin del microcontrolador. */ initports(); inituart(0xff); init_watchdog(1); /* Recibe el modo de comunicacin con el modem. */ printf("\ Modem PLC test\r\n\n\ 0 = reset\r\n\ 1 = physical layer\r\n\ 2 = datalink layer\r\n\ 3 = session layer\r\n\n\ "); while(1) { /* Recibe opcin. */ reset_watchdog(); putchar(MODPLC_LAYPROMPT); gets(line); if (strceq(line, "")) continue; /* Verifica si se solicita la reinicializacin del dispositivo. */ if (strceq(line, MODPLC_NORMRESET)) break; /* Verifica si se solicita la inicializacin de la capa fsica. */ if (strceq(line, MODPLC_PHYSICALLAYER)) { printf("\r\n"); modem_phymode(); break; } /* Verifica si se solicita la inicializacin de la capa de enlace. */ if (strceq(line, MODPLC_DATALINKLAYER)) { printf("\r\n"); modem_dlmode(); break;

646

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


} /* Verifica si se solicita la inicializacin de la capa de sesin. */ if (strceq(line, MODPLC_SESSIONLAYER)) { printf("\r\n"); modem_spmode(); break; } } reset(); }

/* Implementacin de funciones privadas. */ /* Funcin modem_phymode: Recibe y procesa comandos de la capa fsica. */ static void modem_phymode(void) { /* Variables. */ short int size; long int waittime; unsigned char sig; unsigned char level; unsigned char iface; unsigned char *ptrval; char line[MODPLC_CMDLINESIZE]; unsigned char str[PHY_PAYLOADSIZE];

/* /* /* /* /*

Tamao del mensaje. */ Tiempo de espera. */ Tipo de seal. */ Nivel de seal. */ Identificador de interfaz fsica. */ /* Puntero al tiempo de espera. */ /* Lnea de comandos. */ /* Mensaje de prueba. */

/* Inicializa los recursos utilizados por la capa fsica. */ phy_init(); /* Recibe y procesa los comandos recibidos. */ while(1) { /* Recibe comandos. */ reset_watchdog(); putchar(MODPLC_NORMPROMPT); gets(line); if (strceq(line, "")) continue; /* Verifica si el comando solicita la operacin de reinicio del dispositivo. */ else if (strceq(line, MODPLCPHY_RESET)) break; /* Verifica si el comando solicita la operacin de envo de trama. */ else if (strceq(line, MODPLCPHY_SNDFRAME)) { modem_inputstream(&iface, sizeof(iface)); modem_inputstream(&size, sizeof(size)); size = usl2b((unsigned short int) size); modem_inputstream(str, size); if (iface == 0) modem_outputint(phy_sndframe(str, size)); else modem_outputint(0); } /* Verifica si el comando solicita la operacin de captura de trama. */ else if (strceq(line, MODPLCPHY_CAPFRAME)) { modem_inputstream(&iface, sizeof(iface)); modem_inputstream(&size, sizeof(size)); size = usl2b((unsigned short int) size); if (iface == 0) modem_outputbyte(phy_capframe(size) != 0);

FernandoArielBeunza79156

647

Tesis de Grado en Ingeniera Informtica


else modem_outputbyte(0); } /* Verifica si el comando solicita la operacin de obtencin de una trama capturada previamente. */ else if (strceq(line, MODPLCPHY_GETFRAME)) { modem_inputstream(&iface, sizeof(iface)); modem_inputstream(&size, sizeof(size)); size = usl2b((unsigned short int) size); size = phy_getframe(str, size); if (iface == 0) { modem_outputint(size); modem_outputstream(str, size); } else modem_outputint(0); } /* Verifica si el comando solicita la operacin de notificacin de recepcin de trama. */ else if (strceq(line, MODPLCPHY_POLL)) { modem_inputstream(&iface, sizeof(iface)); if (iface == 0) modem_outputbyte(phy_poll() != 0); else modem_outputbyte(0); } /* Verifica si el comando solicita la operacin de reenvio de trama. */ else if (strceq(line, MODPLCPHY_RSDFRAME)) { modem_inputstream(&iface, sizeof(iface)); if (iface == 0) modem_outputbyte(phy_rsdframe() != 0); else modem_outputbyte(0); } /* Verifica si el comando solicita la operacin de limpieza del buffer de captura de tramas. */ else if (strceq(line, MODPLCPHY_CLRBUFFER)) { modem_inputstream(&iface, sizeof(iface)); if (iface == 0) modem_outputbyte(phy_clrbuffer() != 0); else modem_outputbyte(0); } /* Verifica si el comando solicita la operacin de sensado del estado del canal de comunicacin. */ else if (strceq(line, MODPLCPHY_SENSECHANNEL)) { modem_inputstream(&iface, sizeof(iface)); modem_inputstream(&level, sizeof(level)); modem_inputstream(str, sizeof(unsigned long int)); ptrval = (unsigned char *) &waittime; ptrval[0] = str[3]; ptrval[1] = str[2]; ptrval[2] = str[1]; ptrval[3] = str[0]; if (iface == 0) modem_outputbyte(phy_sensechannel(level, waittime)); else modem_outputbyte(0); }

648

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Verifica si el comando solicita la operacin de generacin de una seal de prueba. */ else if (strceq(line, MODPLCPHY_GENSIGNAL)) { modem_inputstream(&iface, sizeof(iface)); modem_inputstream(&sig, sizeof(sig)); if (iface == 0) { if (sig == MODPLCPHY_NOISESIGNAL) modem_outputbyte(phy_gennoisesignal() != 0); else if (sig == MODPLCPHY_TESTSIGNAL1) modem_outputbyte(phy_tstsignal1() != 0); else if (sig == MODPLCPHY_TESTSIGNAL2) modem_outputbyte(phy_tstsignal2() != 0); } else modem_outputbyte(0); } /* Verifica si el comando solicita la operacin de prueba de recepcin. */ else if (strceq(line, MODPLCPHY_TSTRECEIVE)) { modem_inputstream(&iface, sizeof(iface)); if (iface == 0) modem_outputbyte(phy_tstreceive() != 0); else modem_outputbyte(0); }

/* Verifica si el comando solicita la operacin de solicitud de tamao mximo de trama. */ else if (strceq(line, MODPLCPHY_GETPAYLOADSIZE)) { modem_inputstream(&iface, sizeof(iface)); if (iface == 0) modem_outputint(PHY_PAYLOADSIZE); else modem_outputint(0); } /* Comando desconocido. */ else continue; printf("\r\n"); } /* Libera los recursos utilizados por la capa fsica. */ phy_release(); } /* Funcin modem_dlmode: Recibe y procesa comandos de la capa de enlace. */ static void modem_dlmode(void) { /* Variables. */ short int hd; short int size; dl_addr dladdr; dl_logaddr logaddr; unsigned char prio; unsigned char prot; unsigned char iface; unsigned char *ptrval; char line[MODPLC_CMDLINESIZE];

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

Manejador de conexin. */ Tamao del mensaje. */ Direccin DL. */ Direccin lgica. */ Prioridad del mensaje. */ Identificador de protocolo. */ Identificador de interfaz fsica. */ /* Puntero a la direccin lgica. */ /* Lnea de comandos. */

FernandoArielBeunza79156

649

Tesis de Grado en Ingeniera Informtica


unsigned char str[DL_PAYLOADSIZE]; /* Mensaje de prueba. */

/* Inicializa los recursos utilizados por la capa de enlace. */ for(iface = 0; iface < NET_PHYINTERFACES; iface++) dl_init(0); /* Recibe y procesa los comandos recibidos. */ while(1) { /* Verifica el estado del dispositivo. */ if (!dl_status(0)) break; /* Recibe comandos. */ reset_watchdog(); putchar(MODPLC_NORMPROMPT); gets(line); if (strceq(line, "")) continue; /* Verifica si el comando solicita la operacin de reinicio del dispositivo. */ else if (strceq(line, MODPLCDL_RESET)) break; /* Verifica si el comando solicita la operacin de apertura de conexin. */ else if (strceq(line, MODPLCDL_OPEN)) { modem_inputstream(&iface, sizeof(iface)); modem_inputstream(&prot, sizeof(prot)); modem_outputint(dl_open(iface, prot)); } /* Verifica si el comando solicita la operacin de cierre de conexin. */ else if (strceq(line, MODPLCDL_CLOSE)) { modem_inputstream(&hd, sizeof(hd)); hd = usl2b((unsigned short int) hd); modem_outputbyte(dl_close(hd) != 0); } /* Verifica si el comando solicita la operacin de envo de mensaje. */ else if (strceq(line, MODPLCDL_SEND)) { modem_inputstream(&hd, sizeof(hd)); hd = usl2b((unsigned short int) hd); modem_inputstream(dladdr, sizeof(dladdr)); modem_inputstream(&prio, sizeof(prio)); modem_inputstream(&size, sizeof(size)); size = usl2b((unsigned short int) size); modem_inputstream(str, size); modem_outputint(dl_send(hd, dladdr, prio, str, size)); } /* Verifica si el comando solicita la operacin lectura de mensaje. */ else if (strceq(line, MODPLCDL_RECEIVE)) { modem_inputstream(&hd, sizeof(hd)); hd = usl2b((unsigned short int) hd); modem_inputstream(&size, sizeof(size)); size = usl2b((unsigned short int) size); if (dl_poll(hd)) size = dl_receive(hd, dladdr, str, size); else size = 0; modem_outputstream(dladdr, sizeof(dladdr)); modem_outputint(size); modem_outputstream(str, size); } /* Verifica si el comando solicita la operacin de notificacin de recepcin de mensaje. */

650

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


else if (strceq(line, MODPLCDL_POLL)) { modem_inputstream(&hd, sizeof(hd)); hd = usl2b((unsigned short int) hd); modem_outputbyte(dl_poll(hd) != 0); } /* Verifica si el comando solicita la operacin de solicitud de direccin fsica del dispositivo. */ else if (strceq(line, MODPLCDL_GETADDRESS)) { modem_inputstream(&iface, sizeof(iface)); if (dl_getaddress(iface, dladdr)) modem_outputstream(dladdr, sizeof(dladdr)); } /* Verifica si el comando solicita la operacin de agregado de una direccin lgica. */ else if (strceq(line, MODPLCDL_ADDLOGADDRESS)) { modem_inputstream(&iface, sizeof(iface)); modem_inputstream(&prot, sizeof(prot)); modem_inputstream(str, sizeof(logaddr)); ptrval = (unsigned char *) &logaddr; ptrval[0] = str[3]; ptrval[1] = str[2]; ptrval[2] = str[1]; ptrval[3] = str[0]; modem_outputbyte(dl_addlogaddress(iface, prot, logaddr) != 0); } /* Verifica si el comando solicita la operacin de eliminacin de una direccin lgica. */ else if (strceq(line, MODPLCDL_DELLOGADDRESS)) { modem_inputstream(&iface, sizeof(iface)); modem_inputstream(&prot, sizeof(prot)); modem_inputstream(str, sizeof(logaddr)); ptrval = (unsigned char *) &logaddr; ptrval[0] = str[3]; ptrval[1] = str[2]; ptrval[2] = str[1]; ptrval[3] = str[0]; modem_outputbyte(dl_dellogaddress(iface, prot, logaddr) != 0); } /* Verifica si el comando solicita la operacin de solicitud de direccin fsica asociada. */ else if (strceq(line, MODPLCDL_GETPHYADDRESS)) { modem_inputstream(&iface, sizeof(iface)); modem_inputstream(&prot, sizeof(prot)); modem_inputstream(str, sizeof(logaddr)); ptrval = (unsigned char *) &logaddr; ptrval[0] = str[3]; ptrval[1] = str[2]; ptrval[2] = str[1]; ptrval[3] = str[0]; if (dl_getphyaddress(iface, prot, logaddr, dladdr)) modem_outputstream(dladdr, sizeof(dladdr)); } /* Verifica si el comando solicita la operacin de solicitud de tamao mximo de mensaje. */ else if (strceq(line, MODPLCDL_GETPAYLOADSIZE)) { modem_inputstream(&iface, sizeof(iface)); modem_outputint(dl_getpayloadsize(iface)); } /* Comando desconocido. */

FernandoArielBeunza79156

651

Tesis de Grado en Ingeniera Informtica


else continue; printf("\r\n"); } /* Libera los recursos utilizados por la capa de enlace. */ for(iface = 0; iface < NET_PHYINTERFACES; iface++) dl_release(iface); } /* Funcin modem_spmode: Recibe y procesa comandos de la capa de la capa de sesin. */ static void modem_spmode(void) { /* Variables. */ unsigned char nosec; short int size; sp_grpid grpid; char line[MODPLC_CMDLINESIZE]; unsigned char str[SP_PAYLOADSIZE];

/* Indicador de mensaje fuera de secuencia. */ /* Tamao del mensaje. */ /* Identificador de grupo. */ /* Lnea de comandos. */ /* Mensaje de prueba. */

/* Inicializa los recursos utilizados por la capa de sesin. */ sp_init(); /* Recibe y procesa los comandos recibidos. */ while(1) { /* Verifica el estado del dispositivo. */ if (!sp_status()) break; /* Recibe comandos. */ reset_watchdog(); putchar(MODPLC_NORMPROMPT); gets(line); if (strceq(line, "")) continue; /* Verifica si el comando solicita la operacin de reinicio del dispositivo. */ else if (strceq(line, MODPLCSP_RESET)) break; /* Verifica si el comando solicita la operacin de establece la propiedad del grupo. */ else if (strceq(line, MODPLCSP_PUBLISH)) { modem_inputstream(&grpid, sizeof(grpid)); modem_outputbyte(sp_publish(grpid) != 0); } /* Verifica si el comando solicita la operacin de suscripcin a un grupo. */ else if (strceq(line, MODPLCSP_SUBSCRIBE)) { modem_inputstream(&grpid, sizeof(grpid)); modem_outputbyte(sp_subscribe(grpid) != 0); } /* Verifica si el comando solicita la operacin de desvinculacin a un grupo. */ else if (strceq(line, MODPLCSP_LEAVE)) { modem_inputstream(&grpid, sizeof(grpid)); modem_outputbyte(sp_leave(grpid) != 0); } /* Verifica si el comando solicita la operacin de envo de mensaje. */ else if (strceq(line, MODPLCSP_SEND)) {

652

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


modem_inputstream(&grpid, sizeof(grpid)); modem_inputstream(&nosec, sizeof(nosec)); modem_inputstream(&size, sizeof(size)); size = usl2b((unsigned short int) size); modem_inputstream(str, size); size = sp_send(grpid, nosec, str, size); modem_outputint(size); } /* Verifica si el comando solicita la operacin lectura de mensaje. */ else if (strceq(line, MODPLCSP_RECEIVE)) { modem_inputstream(&size, sizeof(size)); size = usl2b((unsigned short int) size); if (sp_poll()) size = sp_receive(&grpid, str, size); else { size = 0; grpid = 0; } modem_outputbyte((unsigned char) grpid); modem_outputint(size); modem_outputstream(str, size); } /* Verifica si el comando solicita la operacin de notificacin de recepcin de mensaje. */ else if (strceq(line, MODPLCSP_POLL)) modem_outputbyte(sp_poll() != 0); /* Verifica si el comando solicita la operacin de solicitud de tamao mximo de mensaje. */ else if (strceq(line, MODPLCSP_GETPAYLOADSIZE)) modem_outputint(sp_getpayloadsize()); /* Comando desconocido. */ else continue; printf("\r\n"); } /* Libera los recursos utilizados por la capa de sesin. */ sp_release(); } /* Funcin modem_outputbyte: Enva un byte de datos. */ static void modem_outputbyte(unsigned char b) { reset_watchdog(); printf("\\%02X\r\n", b); } /* Funcin modem_outputint: Enva un entero de 16 bits de datos. */ static void modem_outputint(short int intval) { /* Variables. */ unsigned char *ptr;

/* Puntero a los datos. */

/* Enva los datos. */ reset_watchdog(); ptr = (char *) &intval; printf("\\%02X\\%02X\r\n", ptr[1], ptr[0]);

FernandoArielBeunza79156

653

Tesis de Grado en Ingeniera Informtica


} /* Funcin modem_outputstream: Enva una trama de datos. */ static void modem_outputstream(const void *str, short int size) { /* Variables. */ short int i; /* Contador. */ unsigned char *ptr; /* Puntero a los datos. */

/* Carga el puntero a los datos a enviar. */ ptr = (unsigned char *) str; /* Enva los datos. */ reset_watchdog(); for(i = 0; i < size; ) { reset_watchdog(); if ((*ptr >= 0x20) && (*ptr <= 0x7e) && (*ptr != ((unsigned char) '\\')) && (*ptr != ((unsigned char) MODPLC_INITPROMPT)) && (*ptr != ((unsigned char) MODPLC_LAYPROMPT)) && (*ptr != ((unsigned char) MODPLC_NORMPROMPT)) && (*ptr != ((unsigned char) MODPLC_PARAMPROMPT))) putchar(*ptr); else printf("\\%02X", *ptr); ptr ++; if ((++ i) & 0x000f) continue; printf("\r\n"); } reset_watchdog(); if ((i & 0x000f) && (size)) printf("\r\n"); } /* Funcin modem_inputstream: Recibe una trama de datos. */ static void modem_inputstream(void *stream, short int size) { /* Variables. */ int i; /* Contador. */ char c; /* Caracter ledo. */ unsigned char dat; /* Byte ledo. */ unsigned char *ptrdat; /* Puntero a los datos. */ unsigned char *ptrline; /* Puntero a la lnea recibida. */ char line[MODPLC_CMDLINESIZE]; /* Lnea de comandos. */

/* Carga el puntero a los datos a enviar. */ ptrdat = (unsigned char *) stream; /* Recibe los datos. */ dat = 0; while(size) { /* Lee una lnea. */ putchar(MODPLC_PARAMPROMPT); gets(line); /* Procesa la lnea leda. */ ptrline = (unsigned char *) line; while(*ptrline) { /* Verifica si se solicita reiniciar el dispositivo. */ if (*ptrline == ((unsigned char) MODPLC_PARAMRESET)) {

654

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


reset(); return; } /* Procesa un caracter de la lnea. */ if (*ptrline != ((unsigned char) '\\')) dat = *(ptrline ++); else { ptrline ++; for(i = 0; i < 2; i++) { dat <<= 4; c = *(ptrline ++); if ((c >= '0') && (c <= '9')) dat += c - '0'; else if ((c >= 'a') && (c <= 'f')) dat += c - 'a' + 0x0a; else if ((c >= 'A') && (c <= 'F')) dat += c - 'A' + 0x0a; } } /* Almacena y devuelve el byte recibido. */ reset_watchdog(); if (!size) continue; *(ptrdat ++) = dat; size --; } } reset_watchdog(); }

C.6. Especificacin del cdigo fuente del firmware procesador de seales


En esta seccin se detalla el cdigo fuente del firmware del procesador de seales compuesto por los siguientes archivos:

Archivo config.h: en este archivo se definen parmetros de configuracin del cargador que no pueden ser modificados, tales como el tamao del smbolo, etc. Archivo phy.h: en este archivo se declaran primitivas con funcionalidades referentes a la envo y recepcin de seales de informacin. Archivo phy.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo phy.h. Archivo main.c: en este archivo se encuentra implementada la rutina principal del firmware procesador de seales.

C.6.1. Archivo config.h


/* config.h: Definicin de parmetros de configuracin.

FernandoArielBeunza79156

655

Tesis de Grado en Ingeniera Informtica


*/

#if !defined(__CONFIG_H__) #define __CONFIG_H__

/* Frecuencia de reloj del microcontrolador. */ #define F_CPU

11059200UL

/* Capa de fsica. */ /* Mxima cantidad de bytes que puede almacenar el buffer. */ #define PHY_PAYLOADSIZE 400 /* Cdigo de operacin de envo de trama. */ #define PHY_SNDFRMOP

0xa9

/* Cdigo de operacin de obtencin de trama capturada. */ #define PHY_GETFRMOP 0xaa /* Cdigo de operacin de captura de trama. */ #define PHY_CAPFRMOP /* Cdigo de operacin de reenvo de trama. */ #define PHY_RSDFRMOP

0xab

0xac

/* Cdigo de operacin de sensado del canal de comunicacin. */ #define PHY_SENSCHOP 0xad /* Cdigo de operacin de generacin de seal de ruido. */ #define PHY_GENNOISEOP 0xae /* Cdigo de limpieza del buffer. */ #define PHY_CRBUFFOP /* Cdigo de generacin de seal de prueba 1. */ #define PHY_TSTSIGOP1 /* Cdigo de generacin de seal de prueba 2. */ #define PHY_TSTSIGOP2 /* Cdigo de prueba de recepcin. */ #define PHY_TSTRCVOP

0xaf

0xba

0xbb

0xbc

#endif

C.6.2. Archivo phy.h


/* phy.h: Declaracin de funciones referentes a la capa fsica. */

#if !defined(__PHY_H__) #define __PHY_H__

/* Archivos includos necesarios. */ #include "config.h" #include <inttypes.h>

/* Definicin de funciones pblicas. */

656

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin phy_init: Inicializa los recursos utilizados por la capa fsica. */ void phy_init(void); /* Funcin phy_exec: Espera y ejecuta la operaciones solicitadas a la capa fsica. */ void phy_exec(void);

#endif

C.6.3. Archivo phy.c


/* phy.c: Implementacin de funciones referentes a la capa fsica. */

/* Archivos includos necesarios. */ #include "config.h" #include <avr/io.h> #include <avr/interrupt.h> #include <inttypes.h>

/* Definicin de constantes. */ /* Nivel de tensin por defecto del generador de seal. */ #define PHY_SIGGENLEVEL 0x07 /* Nivel de tensin por defecto del umbral de deteccin. */ #define PHY_THGENLEVEL 0x09 /* Tiempo mximo de espera entre bytes recibidos. */ #define PHY_TIMEOUTBITS

24

/* Caracter utilizado para calibrar el umbral de deteccin. */ #define PHY_CALTHRBYTE 0x55 /* Caracter utilizado como delimitador de patrn de inicio. */ #define PHY_DELBYTE 0xdb

/* Patrn de bytes de inicio. */ static const uint8_t __phy_startpattern__[] = { 0xff, 0xff, 0x7f, 0xff, 0xff, PHY_CALTHRBYTE, PHY_CALTHRBYTE, PHY_CALTHRBYTE, PHY_CALTHRBYTE, PHY_CALTHRBYTE, PHY_CALTHRBYTE, PHY_CALTHRBYTE, PHY_CALTHRBYTE, 0xff, 0xff, PHY_DELBYTE };

FernandoArielBeunza79156

657

Tesis de Grado en Ingeniera Informtica


/* Patrn de bytes de fin. */ static const uint8_t __phy_endpattern__[] = { 0xff, 0xff };

/* Variables globales. */ /* Cdigo de operacin. */ static volatile uint8_t __phy_buffop__; /* Cantidad de bytes almacenados en el buffer. */ static volatile uint16_t __phy_buffsize__; /* Puntero al contenido del buffer. */ static volatile uint8_t *__phy_buffdata__; /* Buffer de trama. */ static volatile uint8_t __phy_buffer__[PHY_PAYLOADSIZE + sizeof(__phy_startpattern__) + sizeof(__phy_endpattern__)];

/* Declaracin de funciones privadas. */ static uint8_t __phy_recvbyte__(void); static uint8_t __phy_sendbyte__(uint8_t); static void __phy_sndframe__(void); static void __phy_calthreshold__(void); static int __phy_capframe__(void); static int __phy_sensechannel__(uint8_t); static void __phy_gennoisesignal__(void); static void __phy_tstsignal1__(void); static void __phy_tstsignal2__(void); static void __phy_tstreceive__(void);

/* Implementacin de funciones pblicas. */ /* Funcin phy_init: Inicializa los recursos utilizados por la capa fsica. */ void phy_init(void) { /* Variables. */ uint16_t i;

/* Posicin dentro del buffer. */

/* Desactiva las interrupciones. */ cli(); /* Inicializa los DACs. */ DDRA = 0xff; PORTA = ((PHY_SIGGENLEVEL & 0x0f) << 4) | (PHY_THGENLEVEL & 0x0f); /* Inicializa salida de datos recibidos y comparador analgico. */ DDRB = 0x83; ACSR = 0x00; PORTB = 0x03; /* Inicializa entrada de recepcin seal. */ DDRC = 0x00; PORTC = 0x00; /* Inicializa integrador. */ DDRD = 0xff; PORTD = 0x00; /* Inicializa entrada de datos a enviar. */ DDRE = 0x04;

658

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


PORTE = 0x03; /* Inicializa el buffer. */ __phy_buffop__ = 0x00; __phy_buffsize__ = 0; __phy_buffdata__ = __phy_buffer__ + sizeof(__phy_startpattern__); for(i = 0; i < sizeof(__phy_startpattern__); i++) __phy_buffer__[i] = __phy_startpattern__[i]; /* Inicializa la interrupcin INT2. */ EMCUCR &= (0xff ^ (1 << ISC2)); GICR |= (1 << INT2); } /* Funcin phy_exec: Espera y ejecuta la operaciones solicitadas a la capa fsica. */ void phy_exec(void) { sei(); while(1) PORTA = ((PHY_SIGGENLEVEL & 0x0f) << 4) | (PHY_THGENLEVEL & 0x0f); }

/* Implementacin de funciones privadas. */ /* Interrupcin INT2: Recibe solicitudes de operacin. */ ISR(INT2_vect, ISR_BLOCK) { /* Variables. */ uint16_t i; uint16_t buffsize; uint8_t thrlevel;

/* Posicin dentro del buffer. */ /* Cantidad de bytes almacenados en el buffer. */ /* Umbral de deteccin de ocupacin del canal de comunicacin. */

/* Desactiva las interrupciones. */ cli(); /* Verifica el estado de la solicitud de interrupcin. */ if (PINE & 0x01) { sei(); return; } /* Recibe la operacin requerida. */ __phy_buffop__ = __phy_recvbyte__(); /* Verifica si es la envo de trama. */ if (__phy_buffop__ == PHY_SNDFRMOP) { /* Almacena la trama recibida en el buffer. */ i = 0; PORTB |= 0x01; while((!(PINE & 0x01)) && (i < PHY_PAYLOADSIZE)) __phy_buffdata__[i++] = __phy_recvbyte__(); while(!(PINE & 0x01)) __phy_sendbyte__(0xff); PORTB |= 0x01; __phy_buffsize__ = i; for(i = 0; i < sizeof(__phy_endpattern__); i++) __phy_buffdata__[i + __phy_buffsize__] = __phy_endpattern__[i]; /* Enva la trama almacenada en el buffer. */ PORTB &= 0xfe;

FernandoArielBeunza79156

659

Tesis de Grado en Ingeniera Informtica


__phy_sndframe__(); PORTB |= 0x01; } /* Verifica si es la operacin de obtencin de trama capturada. */ else if (__phy_buffop__ == PHY_GETFRMOP) { i = 0; PORTB |= 0x01; while((!(PINE & 0x01)) && (i < __phy_buffsize__)) __phy_sendbyte__(__phy_buffdata__[i++]); while(!(PINE & 0x01)) __phy_sendbyte__(0xff); } /* Verifica si es la operacin de captura de trama. */ else if (__phy_buffop__ == PHY_CAPFRMOP) { PORTB |= 0x01; buffsize = __phy_buffsize__; if (!(PINE & 0x01)) __phy_buffsize__ = __phy_recvbyte__() << 8; if (!(PINE & 0x01)) __phy_buffsize__ |= __phy_recvbyte__(); while(!(PINE & 0x01)) __phy_sendbyte__(0xff); PORTB |= 0x01; if (__phy_buffsize__ > PHY_PAYLOADSIZE) __phy_buffsize__ = PHY_PAYLOADSIZE; if (__phy_buffsize__) { __phy_calthreshold__(); if (__phy_capframe__()) PORTB &= 0xfe; else __phy_buffsize__ = buffsize; } } /* Verifica si es la operacin de reenvo de trama. */ else if (__phy_buffop__ == PHY_RSDFRMOP) { PORTB |= 0x01; while(!(PINE & 0x01)) __phy_sendbyte__(0xff); PORTB |= 0x01; if (__phy_buffsize__) { for(i = 0; i < sizeof(__phy_endpattern__); i++) __phy_buffdata__[i + __phy_buffsize__] = __phy_endpattern__[i]; PORTB &= 0xfe; __phy_sndframe__(); PORTB |= 0x01; } } /* Verifica si es la operacin de sensado del canal de comunicacin. */ else if (__phy_buffop__ == PHY_SENSCHOP) { /* Obtiene el umbral de deteccin de ocupacin del canal de comunicacin. */ PORTB |= 0x01; if (!(PINE & 0x01)) thrlevel = __phy_recvbyte__(); while(!(PINE & 0x01)) __phy_sendbyte__(0xff); /* Sensa el estado del canal de comunicacin. */ if (__phy_sensechannel__(thrlevel)) PORTB &= 0xfe; } /* Verifica si es la operacin de generacin de seal de ruido. */ else if (__phy_buffop__ == PHY_GENNOISEOP) { PORTB |= 0x01; while(!(PINE & 0x01))

660

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


__phy_sendbyte__(0xff); __phy_gennoisesignal__(); } /* Verifica si es la operacin de limpieza del buffer. */ else if (__phy_buffop__ == PHY_CRBUFFOP) { PORTB |= 0x01; while(!(PINE & 0x01)) __phy_sendbyte__(0xff); __phy_buffsize__ = 0; } /* Verifica si es la operacin de generacin de seal de prueba 1. */ else if (__phy_buffop__ == PHY_TSTSIGOP1) { PORTB |= 0x01; while(!(PINE & 0x01)) __phy_sendbyte__(0xff); __phy_tstsignal1__(); } /* Verifica si es la operacin de generacin de seal de prueba 2. */ else if (__phy_buffop__ == PHY_TSTSIGOP2) { PORTB |= 0x01; while(!(PINE & 0x01)) __phy_sendbyte__(0xff); __phy_tstsignal2__(); } /* Verifica si es la operacin de prueba de recepcin. */ else if (__phy_buffop__ == PHY_TSTRCVOP) { PORTB |= 0x01; while(!(PINE & 0x01)) __phy_sendbyte__(0xff); __phy_tstreceive__(); } /* Operacin desconocida. */ else { PORTB |= 0x01; while(!(PINE & 0x01)) __phy_sendbyte__(0xff); } /* Activa las interrupciones. */ sei(); } /* Funcin __phy_recvbyte__: Recibe un byte del mdulo procesamiento. */ static uint8_t __phy_recvbyte__(void) { /* Variables. */ static uint8_t dat;

/* Byte recibido. */

/* Recibe un byte. */ asm volatile("\ push push push push clr ldi L_wait1%=: in andi out sbis rjmp nop

r16 r17 r18 r19 r19 r18, 0x08 r16, %0 r16, (1 << %1) | (1 << %2) %3, r16 %0, %1 L_wait1%=

; ; ; ; ; ; ; ; ; ; ; ;

Guarda contenido de los registros utilizados.

Inicializa el buffer de bits recibidos. Espera comienzo de pulso de sincronismo

\n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

FernandoArielBeunza79156

661

Tesis de Grado en Ingeniera Informtica


in andi nop nop nop out andi lsr or clz ldi nop nop nop nop nop nop breq dec nop nop nop nop nop nop sbic rjmp dec breq lsl rjmp st ldi out pop pop pop pop : : r16, %0 r16, (1 << %1) | (1 << %2) ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Recibe un nuevo bit. \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ "

%3, r16 r16, (1 << %2) r16 r19, r16 r17, %4

Guarda el bit recibido.

Espera fin de pulso de sincronismo.

L_wait2%=:

L_end0%= r17

L_end0%=:

L_end1%=:

%0, %1 L_wait2%= r18 L_end1%= r19 L_wait1%= x, r19 r16, (1 << %1) | (1 << %2) %3, r16 r19 r18 r17 r16 "I" "I" "I" "I" "M" "x" _SFR_IO_ADDR(PINE), (0), (1), _SFR_IO_ADDR(PORTB), ((PHY_TIMEOUTBITS * 5)), (&dat)

Verifica si se completo el byte.

Guarda el byte recibido.

Recupera contenido de los registros utilizados.

); /* Devuelve el byte recibido. */ return dat; } /* Funcin __phy_sendbyte__: Enva un byte al mdulo procesamiento. */ static uint8_t __phy_sendbyte__(uint8_t b) { /* Variables. */ static uint8_t dat;

/* Byte a enviar. */

/* Enva un byte. */ dat = b; asm volatile("\ push push push push ld ldi L_wait1%=: in

r16 r17 r18 r19 r19, x r18, 0x08 r16, %0

; ; ; ; ; ; ;

Guarda contenido de los registros utilizados.

Inicializa el buffer de bits recibidos. Espera comienzo de pulso

\n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

662

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


andi out sbis rjmp nop in andi rol brcc ori out clz ldi nop nop nop nop nop nop nop nop breq dec nop nop nop nop nop nop sbic rjmp dec breq nop rjmp ldi out pop pop pop pop : : r16, (1 << %1) | (1 << %2) %3, r16 %0, %1 L_wait1%= r16, %0 r16, (1 << %1) r19 L_sndbit0%= r16, (1 << %2) %3, r16 r17, %4 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; de sincronismo \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ "

Enva un nuevo bit.

L_sndbit0%=:

Espera fin de pulso de sincronismo.

L_wait2%=:

L_end0%= r17

L_end0%=:

%0, %1 L_wait2%= r18 L_end1%= L_wait1%= r16, (1 << %1) | (1 << %2) %3, r16 r19 r18 r17 r16 "I" "I" "I" "I" "M" "x" _SFR_IO_ADDR(PINE), (0), (1), _SFR_IO_ADDR(PORTB), ((PHY_TIMEOUTBITS * 5)), (&dat)

Verifica si se completo el byte.

L_end1%=:

Recupera contenido de los registros utilizados.

); /* Devuelve el byte envado. */ return dat; } /* Funcin __phy_sndframe__: Enva la trama almacenada en el buffer. */ static void __phy_sndframe__(void) { asm volatile("\ push r2 push r3 push r4 push r5 push r6 push r7 push r8 push r9 push r10 push r11

; Guarda contenido de los ; registros utilizados. ; ; ; ; ; ; ; ;

\n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

FernandoArielBeunza79156

663

Tesis de Grado en Ingeniera Informtica


push push push push push push push push push in mov andi ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi or cp cpc brne rjmp ldi ld sbi nop nop nop nop nop nop nop nop r12 r13 r14 r15 r16 r17 r18 r19 r20 r19, %0 r20, r19 r19, 0x0f r16, 0x90 r2, r16 r2, r19 r16, 0x40 r3, r16 r3, r19 r16, 0x10 r4, r16 r4, r19 r16, 0x20 r5, r16 r5, r19 r16, 0x50 r6, r16 r6, r19 r16, 0x70 r7, r16 r7, r19 r16, 0x60 r8, r16 r8, r19 r16, 0x80 r9, r16 r9, r19 r16, 0x30 r10, r16 r10, r19 r16, 0xa0 r11, r16 r11, r19 r16, 0x00 r12, r16 r12, r19 r16, 0xc0 r13, r16 r13, r19 r16, 0xb0 r14, r16 r14, r19 r16, 0xd0 r15, r16 r15, r19 r16, 0xe0 r16, r19 r30, r26 r31, r27 L_init%= L_end%= r17, 0x07 r18, z+ %1, %2 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ Carga los valores de las \n\t\ muestras. \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ Verifica si ya se \n\t\ procesaron todos los datos \n\t\ almacenados en el buffer. \n\t\ \n\t\ \n\t\ \n\t\ Activa el transmisor. \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

L_init%=:

664

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop sbrc rjmp nop out ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Enva los primeros 7 bits ; de un byte de los datos. ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

r18, 7 L_sndbit1_06_0%= %0, r8

L_sndbit0_06_0%=:

FernandoArielBeunza79156

665

Tesis de Grado en Ingeniera Informtica


out out out out out nop out nop nop out out out lsl dec out out out out out nop out out out out out out out out out out out out out out nop nop out out out out out nop out out out nop out out out out out nop out out out out out out out out out cpi breq nop out out out out out out out %0, %0, %0, %0, %0, r14 r16 r15 r11 r9 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

%0, r2

L_sndbit0_06_1%=:

%0, %0, %0, r18 r17 %0, %0, %0, %0, %0, %0, %0, %0, %0, %0, %0, %0, %0, %0, %0, %0, %0, %0, %0,

r9 r7 r8

r9 r13 r16 r13 r11 r14 r9 r6 r8 r13 r16 r11 r10 r3 r9 r2 r6 r10 r3

%0, %0, %0, %0, %0,

r8 r13 r16 r2 r5

%0, r7 %0, r11 %0, r14 %0, %0, %0, %0, %0, r13 r14 r9 r7 r11

%0, r6 %0, r12 %0, r3 %0, r11 %0, r13 %0, r9 %0, r10 %0, r5 %0, r3 r17, 0x00 L_sndbit0_06_2%= %0, %0, %0, %0, %0, %0, %0, r6 r9 r14 r11 r8 r3 r8

666

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


out nop out out out sbrs rjmp nop out out out out out out nop out rjmp out out out out out out out out nop out out out sbrs rjmp nop out out out out out out nop out rjmp out out out out out out nop out nop nop out out out lsl dec out out out out out nop out out out out out out out out out %0, r14 %0, r8 %0, r4 %0, r5 r18, 7 L_sndbit1_06_0%= %0, %0, %0, %0, %0, %0, r8 r14 r16 r15 r11 r9 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

L_sndbit0_06_2%=:

%0, r2 L_sndbit0_06_1%= %0, r6 %0, r9 %0, r14 %0, r11 %0, r8 %0, r3 %0, r8 %0, r14 %0, r8 %0, r4 %0, r5 r18, 7 L_sndbit1_7_0%= %0, %0, %0, %0, %0, %0, r8 r14 r16 r15 r11 r9

L_sndbit1_06_0%=:

%0, r2 L_sndbit0_7_1%= %0, r2 %0, r3 %0, r4 %0, r5 %0, r6 %0, r7 %0, r8

L_sndbit1_06_1%=:

%0, %0, %0, r18 r17 %0, %0, %0, %0, %0, %0, %0, %0, %0, %0, %0, %0, %0, %0,

r7 r9 r2

r7 r10 r4 r10 r6 r3 r7 r11 r2 r10 r12 r6 r13 r14

FernandoArielBeunza79156

667

Tesis de Grado en Ingeniera Informtica


out out out out out nop nop out out out out out nop out out out nop out out out out out nop out out out out out out out out out cpi breq nop out out out out out out out out nop out out out sbrs rjmp nop out out out out out out nop out rjmp out out out out out out out out nop out out out %0, %0, %0, %0, %0, r7 r8 r11 r13 r14 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

%0, %0, %0, %0, %0,

r2 r10 r4 r8 r15

%0, r9 %0, r6 %0, r3 %0, %0, %0, %0, %0, r10 r3 r7 r9 r6

%0, r11 %0, r16 %0, r14 %0, r6 %0, r10 %0, r7 %0, r13 %0, r15 %0, r14 r17, 0x00 L_sndbit1_06_2%= %0, %0, %0, %0, %0, %0, %0, %0, r11 r7 r3 r6 r2 r14 r2 r3

%0, r2 %0, r16 %0, r15 r18, 7 L_sndbit0_06_0%= %0, %0, %0, %0, %0, %0, r2 r3 r4 r5 r6 r7

L_sndbit1_06_2%=:

%0, r8 L_sndbit1_06_1%= %0, r11 %0, r7 %0, r3 %0, r6 %0, r2 %0, r14 %0, r2 %0, r3 %0, r2 %0, r16 %0, r15

668

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


sbrs rjmp nop out out out out out out nop out rjmp out out out out out out nop out nop nop out out out ld out out out out out ldi out out out out out out out out out out out out out out nop nop out out out out out nop out out out cp out out out out out cpc out out out out out out out r18, 7 L_sndbit0_7_0%= %0, %0, %0, %0, %0, %0, r2 r3 r4 r5 r6 r7 ; ; ; ; ; ; ; ; ; ; ; ; Enva el ltimo bit de un ; byte de los datos. ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

L_sndbit0_7_0%=:

%0, r8 L_sndbit1_7_1%= %0, r8 %0, r14 %0, r16 %0, r15 %0, r11 %0, r9 %0, r2

L_sndbit0_7_1%=:

%0, r9 %0, r7 %0, r8 r18, z+ %0, r9 %0, r13 %0, r16 %0, r13 %0, r11 r17, 0x07 %0, r14 %0, r9 %0, r6 %0, r8 %0, r13 %0, r16 %0, r11 %0, r10 %0, r3 %0, r9 %0, r2 %0, r6 %0, r10 %0, r3

%0, %0, %0, %0, %0,

r8 r13 r16 r2 r5

%0, r7 %0, r11 %0, r14 r30, r26 %0, r13 %0, r14 %0, r9 %0, r7 %0, r11 r31, r27 %0, r6 %0, r12 %0, r3 %0, r11 %0, r13 %0, r9 %0, r10

FernandoArielBeunza79156

669

Tesis de Grado en Ingeniera Informtica


out out breq nop nop out out out out out out out out nop out out out sbrs rjmp nop out out out out out out nop out rjmp nop out out out out out out out out nop out out out nop rjmp out out out out out out nop out nop nop out out out ld out out out out out ldi out out out out out out out %0, r5 %0, r3 L_sndbit0_7_2%= ; ; ; Verifica si ya se ; procesaron todos los datos ; almacenados en el buffer. ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

%0, %0, %0, %0, %0, %0, %0, %0,

r6 r9 r14 r11 r8 r3 r8 r14

%0, r8 %0, r4 %0, r5 r18, 7 L_sndbit1_06_0%= %0, %0, %0, %0, %0, %0, r8 r14 r16 r15 r11 r9

%0, r2 L_sndbit0_06_1%= %0, %0, %0, %0, %0, %0, %0, %0, r6 r9 r14 r11 r8 r3 r8 r14

L_sndbit0_7_2%=:

%0, r8 %0, r4 %0, r5 L_end%= %0, r2 %0, r3 %0, r4 %0, r5 %0, r6 %0, r7 %0, r8

L_sndbit1_7_0%=:

L_sndbit1_7_1%=:

%0, r7 %0, r9 %0, r2 r18, z+ %0, r7 %0, r10 %0, r4 %0, r10 %0, r6 r17, 0x07 %0, r3 %0, r7 %0, r11 %0, r2 %0, r10 %0, r12 %0, r6

670

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


out out out out out out out nop nop out out out out out nop out out out cp out out out out out cpc out out out out out out out out out breq nop nop out out out out out out out out nop out out out sbrs rjmp nop out out out out out out nop out rjmp nop out out out out out out out out nop %0, %0, %0, %0, %0, %0, %0, r13 r14 r7 r8 r11 r13 r14 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Verifica si ya se ; procesaron todos los datos ; almacenados en el buffer. ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

%0, %0, %0, %0, %0,

r2 r10 r4 r8 r15

%0, r9 %0, r6 %0, r3 r30, r26 %0, r10 %0, r3 %0, r7 %0, r9 %0, r6 r31, r27 %0, r11 %0, r16 %0, r14 %0, r6 %0, r10 %0, r7 %0, r13 %0, r15 %0, r14 L_sndbit1_7_2%=

%0, %0, %0, %0, %0, %0, %0, %0,

r11 r7 r3 r6 r2 r14 r2 r3

%0, r2 %0, r16 %0, r15 r18, 7 L_sndbit0_06_0%= %0, %0, %0, %0, %0, %0, r2 r3 r4 r5 r6 r7

%0, r8 L_sndbit1_06_1%= %0, %0, %0, %0, %0, %0, %0, %0, r11 r7 r3 r6 r2 r14 r2 r3

L_sndbit1_7_2%=:

FernandoArielBeunza79156

671

Tesis de Grado en Ingeniera Informtica


out out out nop nop nop cbi out pop pop pop pop pop pop pop pop pop pop pop pop pop pop pop pop pop pop pop : : "I" "I" "I" "x" %0, r2 %0, r16 %0, r15 ; ; ; ; ; ; ; Desactiva el transmisor. ; ; Recupera contenido de los ; registros utilizados. ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ "

L_end%=:

%1, %2 %0, r19 r20 r19 r18 r17 r16 r15 r14 r13 r12 r11 r10 r9 r8 r7 r6 r5 r4 r3 r2

_SFR_IO_ADDR(PORTA), _SFR_IO_ADDR(PORTE), (2), (__phy_buffer__ + sizeof(__phy_startpattern__) + __phy_buffsize__ + sizeof(__phy_endpattern__)), "z" (__phy_buffer__)

); } /* Funcin __phy_calthreshold__: Calibra el umbral de deteccin utilizado para determinar el valor de los bits recibidos. */ static void __phy_calthreshold__(void) { /* Variables. */ uint8_t b; uint8_t thl; uint8_t sbyte; uint8_t thlevel; uint8_t thlevels;

/* /* /* /*

Cantidad de bits. */ Umbral de deteccin. */ Valor del byte sensado. */ Acumulador de umbrales vlidos. */ /* Cantidad de umbrales vlidos. */

/* Inicializa el integrador. */ PORTD = 0x00; PORTB |= 0x80; PORTB &= 0x7f; asm volatile("\ push r16 ldi r16, 0x19 L_continue%=: dec r16 brne L_continue%= nop pop r16 : : ); /* Determina el umbral de deteccin. */ thlevel = 0; thlevels = 0;

; ; ; ; ; ;

\n\t\ \n\t\ \n\t\ \n\t\ \n\t\ "

672

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


for(thl = 0; { sbyte PORTA for(b { thl < 0x10; thl++) = 0x00; = ((PHY_SIGGENLEVEL & 0x0f) << 4) | thl; = 0; b < 8; b++) /* Genera un bit de prueba. */ if (PHY_CALTHRBYTE & (0x80 >> b)) PORTD = 0xff; else PORTD = 0x00; /* Espera. */ asm volatile("\ nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop : : ); /* Sensa el valor del bit. */ sbyte <<= 1; if (ACSR & 0x20) sbyte |= 0x01; /* Espera. */ asm volatile("\ push r16 ldi r16, 0x13 dec r16 brne L_continue%= nop nop pop r16 : : ); } /* Verifica si el umbral es vlido. */ if (sbyte == PHY_CALTHRBYTE) { thlevel += thl; thlevels ++; } } /* Ajusta el umbral de deteccin. */ if (thlevels) thlevel /= thlevels; else thlevel = PHY_THGENLEVEL; PORTA = ((PHY_SIGGENLEVEL & 0x0f) << 4) | thlevel; /* Reinicia el integrador. */ PORTB |= 0x80; PORTB &= 0x7f; }

; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;

\n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ "

L_continue%=:

; ; ; ; ; ; ;

\n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ "

FernandoArielBeunza79156

673

Tesis de Grado en Ingeniera Informtica


/* Funcin __phy_capframe__: Captura una trama y la almacena en el buffer. */ static int __phy_capframe__(void) { /* Variables. */ uint8_t sreg; int capstatus;

/* Contenido del registro de estado. */ /* Estado de la captura. */

/* Guarda el contenido del registro de estado. */ sreg = SREG; /* Realiza la captura. */ asm volatile("\ push r2 push r3 push r4 push r5 push r6 push r7 push r8 push r9 push r10 push r11 push r16 push r17 push r18 push r19 push r20 push r21 ldi r16, 0x00 out %1, r16 mov r2, r16 mov r3, r16 mov r4, r16 mov r5, r16 mov r6, r16 mov r7, r16 mov r8, r16 mov r9, r16 mov r10, r16 mov r11, r16 L_init_rx%=: ldi r17, 0x00 ldi r18, %9 sbi %2, %3 clr r19 ldi r16, 0x1a L_wait_rx_0%=: dec r16 brne L_wait_rx_0%= in r21, %8 cbi %2, %3 L_sense_rx%=: in r16, %0 com r16 out %1, r16 nop nop sbis %4, %5 rjmp L_calth_rx_0%= nop in r16, %0 com r16 out %1, r16 nop nop sbis %4, %5 rjmp L_calth_rx_0%= nop

; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;

Guarda contenido de los registros utilizados.

Inicializa la lnea de retardo.

Inicializa el integrador.

Sensa el canal de comunicacin a la espera de registrar actividad.

\n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

674

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


in com out nop nop sbis rjmp nop in com out nop nop sbis rjmp nop in com out nop nop sbis rjmp nop in com out nop nop sbis rjmp nop in com out nop nop sbis rjmp nop in com out nop nop sbis rjmp nop in com out nop nop sbis rjmp nop in com out nop sbis rjmp rjmp in eor out mov sbis clr sbic inc r16, %0 r16 %1, r16 ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; Inicia reajuste del umbral \n\t\ ; de deteccin. \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\

%4, %5 L_calth_rx_0%= r16, %0 r16 %1, r16

%4, %5 L_calth_rx_0%= r16, %0 r16 %1, r16

%4, %5 L_calth_rx_0%= r16, %0 r16 %1, r16

%4, %5 L_calth_rx_0%= r16, %0 r16 %1, r16

%4, %5 L_calth_rx_0%= r16, %0 r16 %1, r16

%4, %5 L_calth_rx_0%= r16, %0 r16 %1, r16

%4, %5 L_calth_rx_0%= r16, %0 r16 %1, r16 %6, %7 L_end_0%= L_sense_rx%= r16, %0 r2, r16 %1, r2 r2, r16 %4, %5 r19 %4, %5 r19

L_calth_rx_0%=:

FernandoArielBeunza79156

675

Tesis de Grado en Ingeniera Informtica


in eor out mov lsl nop nop nop in eor out mov nop nop nop nop in eor out mov nop nop nop nop in eor out mov nop nop nop nop in eor out mov sbis clr sbic inc in eor out mov cpi brlo ori clr in eor out mov nop sbis rjmp nop in eor out mov cpse rjmp nop nop in eor out mov ldi out rjmp r16, %0 r3, r16 %1, r3 r3, r16 r17 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Detecta el valor del bit ; recibido. ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

r16, %0 r4, r16 %1, r4 r4, r16

r16, %0 r5, r16 %1, r5 r5, r16

r16, %0 r6, r16 %1, r6 r6, r16

L_calth_rx_1%=:

r16, %0 r7, r16 %1, r7 r7, r16 %4, %5 r19 %4, %5 r19 r16, %0 r8, r16 %1, r8 r8, r16 r19, 0x01 L_calth_rx_1%= r17, 0x01 r19 r16, %0 r9, r16 %1, r9 r9, r16 %6, %7 L_end_0%= r16, %0 r10, r16 %1, r10 r10, r16 r17, r18 L_calth_rx_2%=

r16, %0 r11, r16 %1, r11 r11, r16 r20, 0x0f %8, r20 L_calth_rx_3%=

676

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


L_calth_rx_2%=: nop in eor out mov nop nop rjmp in eor out mov sbis clr sbic inc in eor out mov lsl nop nop nop in eor out mov nop nop nop nop in eor out mov nop nop nop nop in eor out mov nop nop nop nop in eor out mov sbis clr sbic inc in eor out mov cpi brlo ori clr in eor out mov nop nop nop r16, %0 r11, r16 %1, r11 r11, r16 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

L_calth_rx_3%=:

L_calth_rx_0%= r16, %0 r2, r16 %1, r2 r2, r16 %4, %5 r19 %4, %5 r19 r16, %0 r3, r16 %1, r3 r3, r16 r17

Reajuste del umbral de deteccin.

r16, %0 r4, r16 %1, r4 r4, r16

r16, %0 r5, r16 %1, r5 r5, r16

r16, %0 r6, r16 %1, r6 r6, r16

L_calth_rx_4%=:

r16, %0 r7, r16 %1, r7 r7, r16 %4, %5 r19 %4, %5 r19 r16, %0 r8, r16 %1, r8 r8, r16 r19, 0x01 L_calth_rx_4%= r17, 0x01 r19 r16, %0 r9, r16 %1, r9 r9, r16

Detecta el valor del bit recibido.

FernandoArielBeunza79156

677

Tesis de Grado en Ingeniera Informtica


nop in eor out mov nop nop nop nop in eor out mov nop nop nop nop in eor out mov sbis clr sbic inc in eor out mov lsl nop nop nop in eor out mov nop nop nop nop in eor out mov nop nop nop nop in eor out mov nop cpse rjmp nop in eor out mov sbis clr sbic inc in eor out mov cpi brlo r16, %0 r10, r16 %1, r10 r10, r16 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Detecta el valor del bit ; recibido. \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

r16, %0 r11, r16 %1, r11 r11, r16

r16, %0 r2, r16 %1, r2 r2, r16 %4, %5 r19 %4, %5 r19 r16, %0 r3, r16 %1, r3 r3, r16 r17

r16, %0 r4, r16 %1, r4 r4, r16

r16, %0 r5, r16 %1, r5 r5, r16

r16, %0 r6, r16 %1, r6 r6, r16 r20, 0x00 L_calth_rx_7%= r16, %0 r7, r16 %1, r7 r7, r16 %4, %5 r19 %4, %5 r19 r16, %0 r8, r16 %1, r8 r8, r16 r19, 0x01 L_calth_rx_5%=

678

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


L_calth_rx_5%=: ori clr in eor out mov nop sbis rjmp nop in eor out mov cpse rjmp nop nop in eor out mov nop out rjmp nop in eor out mov mov out rjmp in eor out mov sbis clr sbic inc in eor out mov cpi brlo ori clr in eor out mov nop sbis rjmp nop in eor out mov cpse rjmp nop nop eor out mov dec out rjmp r17, 0x01 r19 r16, %0 r9, r16 %1, r9 r9, r16 %6, %7 L_end_0%= r16, %0 r10, r16 %1, r10 r10, r16 r17, r18 L_calth_rx_6%= ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

Verifica si el ajuste es vlido.

r16, %0 r11, r16 %1, r11 r11, r16 %8, r20 L_calth_rx_10%= r16, %0 r11, r16 %1, r11 r11, r16 r20, r21 %8, r20 L_init_rx%= r16, %0 r7, r16 %1, r7 r7, r16 %4, %5 r19 %4, %5 r19 r16, %0 r8, r16 %1, r8 r8, r16 r19, 0x01 L_calth_rx_8%= r17, 0x01 r19 r16, %0 r9, r16 %1, r9 r9, r16 %6, %7 L_end_0%= r16, %0 r10, r16 %1, r10 r10, r16 r17, r18 L_calth_rx_9%=

L_calth_rx_6%=:

L_calth_rx_7%=:

Detecta el valor del segundo bit recibido.

L_calth_rx_8%=:

Verifica si el ajuste es vlido.

r11, r16 %1, r11 r11, r16 r20 %8, r20 L_calth_rx_10%=

FernandoArielBeunza79156

679

Tesis de Grado en Ingeniera Informtica


L_calth_rx_9%=: nop in eor out mov dec out rjmp in eor out mov sbis clr sbic inc in eor out mov lsl ldi nop nop in eor out mov nop nop nop nop in eor out mov nop nop nop nop in eor out mov nop nop nop nop in eor out mov sbis clr sbic inc in eor out mov cpi brlo ori clr in eor out mov nop sbis rjmp r16, %0 r11, r16 %1, r11 r11, r16 r20 %8, r20 L_calth_rx_3%= r16, %0 r2, r16 %1, r2 r2, r16 %4, %5 r19 %4, %5 r19 r16, %0 r3, r16 %1, r3 r3, r16 r17 r18, 0xff ; ; ; ; ; ; ; ; ; Fin de reajuste. ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Detecta el valor del bit ; recibido. ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

L_calth_rx_10%=:

r16, %0 r4, r16 %1, r4 r4, r16

r16, %0 r5, r16 %1, r5 r5, r16

r16, %0 r6, r16 %1, r6 r6, r16

L_calth_rx_11%=:

r16, %0 r7, r16 %1, r7 r7, r16 %4, %5 r19 %4, %5 r19 r16, %0 r8, r16 %1, r8 r8, r16 r19, 0x01 L_calth_rx_11%= r17, 0x01 r19 r16, %0 r9, r16 %1, r9 r9, r16 %6, %7 L_end_0%=

680

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


nop in eor out mov cpse rjmp nop nop in eor out mov inc out rjmp nop in eor out mov nop nop rjmp sbi ldi nop nop nop cbi in eor out mov sbis clr sbic inc in eor out mov lsl nop nop nop in eor out mov nop nop nop nop in eor out mov nop nop nop nop in eor out mov nop nop nop nop in r16, %0 r10, r16 %1, r10 r10, r16 r17, r18 L_calth_rx_12%= ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

Verifica el fin del proceso de ajuste.

r16, %0 r11, r16 %1, r11 r11, r16 r20 %8, r20 L_calth_rx_13%= r16, %0 r11, r16 %1, r11 r11, r16

L_calth_rx_12%=:

L_calth_rx_13%=:

L_calth_rx_10%= %2, %3 r18, %10

Reinicia el integrador.

L_start_rx_0%=:

%2, %3 r16, %0 r2, r16 %1, r2 r2, r16 %4, %5 r19 %4, %5 r19 r16, %0 r3, r16 %1, r3 r3, r16 r17

Espera el delimitador.

r16, %0 r4, r16 %1, r4 r4, r16

r16, %0 r5, r16 %1, r5 r5, r16

r16, %0 r6, r16 %1, r6 r6, r16

r16, %0

FernandoArielBeunza79156

681

Tesis de Grado en Ingeniera Informtica


eor out mov sbis clr sbic inc in eor out mov cpi brlo ori clr in eor out mov nop sbis rjmp nop in eor out mov cpse rjmp nop nop in eor out mov nop ldi rjmp nop in eor out mov nop nop rjmp in eor out mov sbis clr sbic inc in eor out mov lsl nop nop nop in eor out mov nop nop nop nop in r7, r16 %1, r7 r7, r16 %4, %5 r19 %4, %5 r19 r16, %0 r8, r16 %1, r8 r8, r16 r19, 0x01 L_setbit_rx_0%= r17, 0x01 r19 r16, %0 r9, r16 %1, r9 r9, r16 %6, %7 L_end_0%= r16, %0 r10, r16 %1, r10 r10, r16 r17, r18 L_cont_rx_0%= ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; Detecta el valor del bit \n\t\ ; recibido. \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; Recibe los bytes restantes \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\ ; \n\t\

L_setbit_rx_0%=:

r16, %0 r11, r16 %1, r11 r11, r16 r18, 0x08 L_start_rx_1%= r16, %0 r11, r16 %1, r11 r11, r16

L_cont_rx_0%=:

L_start_rx_1%=:

L_start_rx_0%= r16, %0 r2, r16 %1, r2 r2, r16 %4, %5 r19 %4, %5 r19 r16, %0 r3, r16 %1, r3 r3, r16 r17

r16, %0 r4, r16 %1, r4 r4, r16

r16, %0

682

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


eor out mov nop nop nop nop in eor out mov nop nop nop nop in eor out mov sbis clr sbic inc in eor out mov cpi brlo ori clr in eor out mov cp cpc brne rjmp in eor out mov dec brne ldi nop in eor out mov st rjmp nop in eor out mov nop nop rjmp clt rjmp set ldi out sbi nop ldi dec brne r5, r16 %1, r5 r5, r16 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

r16, %0 r6, r16 %1, r6 r6, r16

L_setbit_rx_1%=:

L_cont_rx_1%=:

r16, %0 r7, r16 %1, r7 r7, r16 %4, %5 r19 %4, %5 r19 r16, %0 r8, r16 %1, r8 r8, r16 r19, 0x01 L_setbit_rx_1%= r17, 0x01 r19 r16, %0 r9, r16 %1, r9 r9, r16 r30, r26 r31, r27 L_cont_rx_1%= L_end_1%= r16, %0 r10, r16 %1, r10 r10, r16 r18 L_cont_rx_2%= r18, 0x08 r16, %0 r11, r16 %1, r11 r11, r16 z+, r17 L_start_rx_1%= r16, %0 r11, r16 %1, r11 r11, r16

Detecta el valor del bit recibido.

Verifica si la captura se encuentra completa.

L_cont_rx_2%=:

L_start_rx_1%= L_end_2%= r16, 0x00 %1, r16 %2, %3 r16, 0x1a r16 L_wait_rx_2%=

L_end_0%=: L_end_1%=: L_end_2%=:

Interrupcin de captura. Fin de captura.

Reinicia el integrador.

L_wait_rx_2%=:

FernandoArielBeunza79156

683

Tesis de Grado en Ingeniera Informtica


nop cbi pop pop pop pop pop pop pop pop pop pop pop pop pop pop pop pop : : "I" "I" "I" "I" "I" "I" "I" "I" "I" "M" "M" "x" "z" %2, %3 r21 r20 r19 r18 r17 r16 r11 r10 r9 r8 r7 r6 r5 r4 r3 r2 ; ; ; Recupera contenido de los ; registros utilizados. ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ "

_SFR_IO_ADDR(PINC), _SFR_IO_ADDR(PORTD), _SFR_IO_ADDR(PORTB), (7), _SFR_IO_ADDR(ACSR), (5), _SFR_IO_ADDR(PINE), (0), _SFR_IO_ADDR(PORTA), (PHY_CALTHRBYTE), (PHY_DELBYTE), (__phy_buffdata__ + __phy_buffsize__), (__phy_buffdata__)

); /* Obtiene el resultado de la captura. */ capstatus = 0; if (SREG & 0x40) capstatus = 1; /* Recupera el contenido del registro de estado. */ SREG = sreg; /* Devuelve el resultado de la captura. */ return capstatus; } /* Funcin __phy_sensechannel__: Sensa la actividad del canal de comunicacin. */ static int __phy_sensechannel__(uint8_t thrlevel) { /* Variables. */ uint8_t sreg; uint8_t thrstatus; int capstatus;

/* Contenido del registro de estado. */ /* Estado del canal de comunicacin. */ /* Estado de la captura. */

/* Guarda el contenido del registro de estado. */ sreg = SREG; /* Guarda el umbral de deteccin actual. */ thrstatus = PORTA; /* Modifica el umbral de deteccin. */ PORTA = (PORTA & 0xf0) | (thrlevel & 0x0f); /* Sensa el canal de comunicacin. */ asm volatile("\ push r16

\n\t\

684

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


ldi out sbi ldi dec brne cbi ldi in com out nop sbis rjmp nop nop in com out nop nop nop nop nop in com out nop nop nop nop nop in com out nop nop nop nop nop in com out nop nop nop nop nop in com out nop nop nop nop nop in com out nop nop nop nop nop in com out nop nop nop nop r16, 0x00 %1, r16 %2, %3 r16, 0x1a r16 L_wait_0%= %2, %3 r17, 0xff r16, %0 r16 %1, r16 %4, %5 L_end_1%= ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Inicializa el integrador. \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ Inicia el sensado de canal \n\t\ de comunicacin. \n\t\ \n\t\ \n\t\ Verifica el alcance del \n\t\ umbral de deteccin. \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

L_wait_0%=:

L_sense_ch%=:

r16, %0 r16 %1, r16

r16, %0 r16 %1, r16

r16, %0 r16 %1, r16

r16, %0 r16 %1, r16

r16, %0 r16 %1, r16

r16, %0 r16 %1, r16

r16, %0 r16 %1, r16

FernandoArielBeunza79156

685

Tesis de Grado en Ingeniera Informtica


nop in com out nop nop nop nop nop in com out nop sbis rjmp rjmp clt rjmp set ldi out sbi nop ldi dec brne nop cbi pop : : r16, %0 r16 %1, r16 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ Verifica solicitud de fin \n\t\ de sensado de canal de \n\t\ comunicacin. \n\t\ Interrupcin de captura. \n\t\ \n\t\ Deteccin de ocupacin del \n\t\ canal de comunicacin. \n\t\ \n\t\ Reinicia el integrador. \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ "

r16, %0 r16 %1, r16 %6, %7 L_end_0%= L_sense_ch%= L_end_2%= r16, 0x00 %1, r16 %2, %3 r16, 0x1a r16 L_wait_1%= %2, %3 r16 "I" "I" "I" "I" "I" "I" "I" "I" _SFR_IO_ADDR(PINC), _SFR_IO_ADDR(PORTD), _SFR_IO_ADDR(PORTB), (7), _SFR_IO_ADDR(ACSR), (5), _SFR_IO_ADDR(PINE), (0)

L_end_0%=: L_end_1%=: L_end_2%=:

L_wait_1%=:

); /* Restaura el umbral de deteccin anterior. */ PORTA = thrstatus; /* Obtiene el resultado de la captura. */ capstatus = 0; if (SREG & 0x40) capstatus = 1; /* Recupera el contenido del registro de estado. */ SREG = sreg; /* Devuelve el resultado de la captura. */ return capstatus; } /* Funcin __phy_gennoisesignal__: Genera una seal de ruido. */ static void __phy_gennoisesignal__(void) { asm volatile("\ push r2 push r3 push r4 push r5 push r6 push r7 push r8 push r9 push r16 push r17

; Guarda contenido de los ; registros utilizados. ; ; ; ; ; ; ; ;

\n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

686

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


push push in mov andi ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi or ldi sbi mov ori clc ror ror eor ror nop nop nop nop nop nop nop nop nop nop nop nop nop r18 r19 r17, %0 r20, r17 r17, 0x0f r16, 0x90 r2, r16 r2, r17 r16, 0x40 r3, r16 r3, r17 r16, 0x10 r4, r16 r4, r17 r16, 0x20 r5, r16 r5, r17 r16, 0x50 r6, r16 r6, r17 r16, 0x70 r7, r16 r7, r17 r16, 0x60 r8, r16 r8, r17 r16, 0x80 r9, r16 r9, r17 r16, 0x30 r10, r16 r10, r17 r16, 0xa0 r11, r16 r11, r17 r16, 0x00 r12, r16 r12, r17 r16, 0xc0 r13, r16 r13, r17 r16, 0xb0 r14, r16 r14, r17 r16, 0xd0 r15, r16 r15, r17 r16, 0xe0 r16, r17 r18, 0x00 %1, %2 r19, r18 r19, 0x80 r19 r19 r18, r19 r18 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

Carga los valores de las muestras.

Inicializa la semilla. Activa el transmisor.

FernandoArielBeunza79156

687

Tesis de Grado en Ingeniera Informtica


nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop sbrc rjmp nop out out out out out out nop out nop nop out out out ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Genera la seal de ruido ; pseudoaleatorio. ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

r18, 7 L_genbit1%= %0, %0, %0, %0, %0, %0, r8 r14 r16 r15 r11 r9

L_genbit0_0%=:

%0, r2

L_genbit0_1%=:

%0, r9 %0, r7 %0, r8

688

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


mov ori out out out out out clc out out out out out out out out out out out out out out ror ror out out out out out eor out out out ror out out out out out nop out out out out out out out out out nop sbis rjmp out out out out out out out out nop out out out sbrs rjmp nop out out out out r19, r18 r19, 0x80 %0, r9 %0, r13 %0, r16 %0, r13 %0, r11 %0, r14 %0, r9 %0, r6 %0, r8 %0, r13 %0, r16 %0, r11 %0, r10 %0, r3 %0, r9 %0, r2 %0, r6 %0, r10 %0, r3 r19 r19 %0, r8 %0, r13 %0, r16 %0, r2 %0, r5 r18, r19 %0, r7 %0, r11 %0, r14 r18 %0, r13 %0, r14 %0, r9 %0, r7 %0, r11 %0, %0, %0, %0, %0, %0, %0, %0, %0, r6 r12 r3 r11 r13 r9 r10 r5 r3 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Verifica solicitud de fin ; de generacin de ruido. ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

%3, %4 L_end%= %0, r6 %0, r9 %0, r14 %0, r11 %0, r8 %0, r3 %0, r8 %0, r14 %0, r8 %0, r4 %0, r5 r18, 7 L_genbit0_0%= %0, %0, %0, %0, r2 r3 r4 r5

L_genbit1%=:

FernandoArielBeunza79156

689

Tesis de Grado en Ingeniera Informtica


out out nop out nop nop out out out mov ori out out out out out clc out out out out out out out out out out out out out out ror ror out out out out out eor out out out ror out out out out out nop out out out out out out out out out nop sbis rjmp out out out out out out out out nop out %0, r6 %0, r7 %0, r8 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Verifica solicitud de fin ; de generacin de ruido. ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

%0, r7 %0, r9 %0, r2 r19, r18 r19, 0x80 %0, r7 %0, r10 %0, r4 %0, r10 %0, r6 %0, r3 %0, r7 %0, r11 %0, r2 %0, r10 %0, r12 %0, r6 %0, r13 %0, r14 %0, r7 %0, r8 %0, r11 %0, r13 %0, r14 r19 r19 %0, r2 %0, r10 %0, r4 %0, r8 %0, r15 r18, r19 %0, r9 %0, r6 %0, r3 r18 %0, r10 %0, r3 %0, r7 %0, r9 %0, r6 %0, %0, %0, %0, %0, %0, %0, %0, %0, r11 r16 r14 r6 r10 r7 r13 r15 r14

%3, %4 L_end%= %0, r11 %0, r7 %0, r3 %0, r6 %0, r2 %0, r14 %0, r2 %0, r3 %0, r2

690

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


out out sbrc rjmp nop out out out out out out nop out rjmp cbi out pop pop pop pop pop pop pop pop pop pop pop pop : : %0, r16 %0, r15 r18, 7 L_genbit1%= %0, %0, %0, %0, %0, %0, r8 r14 r16 r15 r11 r9 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Desactiva el transmisor. ; ; Recupera contenido de los ; registros utilizados. ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ "

L_end%=:

%0, r2 L_genbit0_1%= %1, %2 %0, r17 r19 r18 r17 r16 r9 r8 r7 r6 r5 r4 r3 r2 "I" "I" "I" "I" "I" _SFR_IO_ADDR(PORTA), _SFR_IO_ADDR(PORTE), (2), _SFR_IO_ADDR(PINE), (0)

); } /* Funcin __phy_tstsignal1__: Genera una seal de prueba. */ static void __phy_tstsignal1__(void) { asm volatile("\ push r2 push r3 push r4 push r5 push r6 push r7 push r8 push r9 push r16 push r17 push r18 in r17, %0 mov r18, r17 andi r17, 0x0f ldi r16, 0x00 mov r2, r16 or r2, r17 ldi r16, 0x10 mov r3, r16 or r3, r17 ldi r16, 0x20 mov r4, r16 or r4, r17 ldi r16, 0x30 mov r5, r16 or r5, r17 ldi r16, 0x40

; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;

Guarda contenido de los registros utilizados.

Carga los valores de las muestras.

\n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

FernandoArielBeunza79156

691

Tesis de Grado en Ingeniera Informtica


mov or ldi mov or ldi mov or ldi mov or sbi out nop out nop nop nop out nop nop nop nop out nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop out nop nop nop nop out nop nop nop out nop nop out nop nop nop out nop nop nop nop out nop nop nop nop nop nop nop r6, r16 r6, r17 r16, 0x50 r7, r16 r7, r17 r16, 0x60 r8, r16 r8, r17 r16, 0x70 r9, r16 r9, r17 %1, %2 %0, r6 %0, r7 ; ; ; ; ; ; ; ; ; ; ; ; Activa el transmisor. ; Genera la seal de prueba. ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

L_continue%=:

%0, r8

%0, r9

%0, r8

%0, r7

%0, r6

%0, r5

%0, r4

%0, r3

692

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


nop out out nop nop nop nop nop nop nop nop out nop nop nop nop out sbis rjmp nop out rjmp out cbi out pop pop pop pop pop pop pop pop pop pop pop : : %0, r2 %0, r3 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ Detiene la seal de prueba \n\t\ si hay una nueva solicitud \n\t\ de operacin. \n\t\ \n\t\ \n\t\ \n\t\ Desactiva el transmisor. \n\t\ \n\t\ Recupera contenido de los \n\t\ registros utilizados. \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ "

%0, r4

%0, r5 %3, %4 L_end%= %0, r6 L_continue%= %0, r6 %1, %2 %0, r18 r18 r17 r16 r9 r8 r7 r6 r5 r4 r3 r2 "I" "I" "I" "I" "I" _SFR_IO_ADDR(PORTA), _SFR_IO_ADDR(PORTE), (2), _SFR_IO_ADDR(PINE), (0)

L_end%=:

); } /* Funcin __phy_tstsignal2__: Genera una seal de prueba. */ static void __phy_tstsignal2__(void) { asm volatile("\ push r2 push r3 push r4 push r5 push r6 push r7 push r8 push r9 push r16 push r17 push r18 in r17, %0 mov r18, r17 andi r17, 0x0f ldi r16, 0x00 mov r2, r16 or r2, r17 ldi r16, 0x10 mov r3, r16

; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;

Guarda contenido de los registros utilizados.

Carga los valores de las muestras.

\n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\

FernandoArielBeunza79156

693

Tesis de Grado en Ingeniera Informtica


or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or ldi mov or sbi out out out out nop nop sbis rjmp out out out out out out out out out out out out out out out out rjmp cbi out pop pop pop pop pop pop pop pop pop pop pop : : r3, r17 r16, 0x20 r4, r16 r4, r17 r16, 0x30 r5, r16 r5, r17 r16, 0x40 r6, r16 r6, r17 r16, 0x50 r7, r16 r7, r17 r16, 0x60 r8, r16 r8, r17 r16, 0x70 r9, r16 r9, r17 %1, %2 %0, r6 %0, r7 %0, r8 %0, r9 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ Activa el transmisor. \n\t\ Genera la seal de prueba. \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ Detiene la seal de prueba \n\t\ si hay una nueva operacin \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ Desactiva el transmisor. \n\t\ \n\t\ Recupera contenido de los \n\t\ registros utilizados. \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ "

L_continue%=:

L_end%=:

%3, %4 L_end%= %0, r8 %0, r7 %0, r6 %0, r5 %0, r4 %0, r3 %0, r3 %0, r2 %0, r3 %0, r3 %0, r4 %0, r5 %0, r6 %0, r7 %0, r8 %0, r9 L_continue%= %1, %2 %0, r18 r18 r17 r16 r9 r8 r7 r6 r5 r4 r3 r2 "I" "I" "I" "I" "I" _SFR_IO_ADDR(PORTA), _SFR_IO_ADDR(PORTE), (2), _SFR_IO_ADDR(PINE), (0)

); } /* Funcin __phy_tstreceive__: Realiza una prueba de recepcin. */

694

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


static void __phy_tstreceive__(void) { asm volatile("\ push r16 L_continue%=: in r16, %0 out %1, r16 nop sbis %2, %3 rjmp L_end%= nop rjmp L_continue%= L_end%=: pop r16 : : "I" _SFR_IO_ADDR(PINC), "I" _SFR_IO_ADDR(PORTD), "I" _SFR_IO_ADDR(PINE), "I" (0) ); }

; ; ; ; ; ; ; ; ;

\n\t\ Repite en el integrador la \n\t\ seal recibida. \n\t\ \n\t\ Detiene la prueba si hay \n\t\ una nueva operacin. \n\t\ \n\t\ \n\t\ "

C.6.4. Archivo main.c


/* main.c: Procesador de seales del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include "phy.h"

/* Funcin main: Funcin principal. */ int main(void) { /* Inicializa los recursos utilizados por la capa fsica. */ phy_init(); /* Espera y ejecuta la operaciones solicitadas a la capa fsica. */ phy_exec(); /* Fin. */ return 0; }

C.7. Especificacin del cdigo fuente del firmware cargador


En esta seccin se detalla el cdigo fuente del firmware del cargador compuesto por los siguientes archivos:

Archivo config.h: en este archivo se definen parmetros de configuracin del cargador que no pueden ser modificados, tales como la posicin de la memoria donde se debe instalar el firmware del modem PLC, el tamao mximo de dicho firmware, etc.

FernandoArielBeunza79156

695

Tesis de Grado en Ingeniera Informtica


Archivo common.h: en este archivo se declaran primitivas con funcionalidades generales. Archivo common.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo common.h. Archivo serial.h: en este archivo se declaran primitivas con funcionalidades referentes a la entrada y salida va puerto RS232. Archivo serial.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo serial.c. Archivo interrupts.h: en este archivo se declaran primitivas de redireccin de las interrupciones. Archivo interrupts.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo interrupts.h. Archivo memory.h: en este archivo se declaran primitivas con funcionalidades referentes a la manipulacin de la memoria donde reside el firmware del modem PLC. Archivo memory.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo memory.h. Archivo boot.c: en este archivo se encuentra implementado el interprete de comandos del cargador, con el cual se interacta por medio del puerto RS232.

C.7.1. Archivo config.h


/* config.h: Definicin de parmetros de configuracin. */

#if !defined(__CONFIG_H__) #define __CONFIG_H__

/* Tamao de la lnea de comandos. */ #define LINE_SIZE

80

/* Cantidad de bytes mxima de cada registro en formato hexadecimal Intel. */ #define RECORD_SIZE 16 /* Comienzo del rea destinada a la memoria de datos del modem PLC. */ #define START_DATA 0x0000 /* Fin del rea destinada a la memoria de datos del modem PLC. */ #define END_DATA 0x7fff /* Comienzo del rea destinada al firmware del modem PLC. */ #define START_FIRMWARE 0x8000 /* Fin del rea destinada al firmware del modem PLC. */ #define END_FIRMWARE

0xffff

696

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


#endif

C.7.2. Archivo common.h


/* common.h: Declaracin de funciones comunes. */

#include "../common/common.h"

C.7.3. Archivo common.c


/* common.c: Implementacin de funciones comunes. */

#include "../common/common.c"

C.7.4. Archivo serial.h


/* serial.h: Declaracin de funciones referentes a la UART. */

#include "../common/serial.h"

C.7.5. Archivo serial.c


/* serial.c: Implementacin de funciones referentes a la UART. */

#include "../common/serial.c"

C.7.6. Archivo interrupts.h


/* interrupts.h: Declaracin de funciones comunes. */

#if !defined(__INTERRUPTS__H__) #define __INTERRUPTS_H__

/* Declaracin de funciones publicas. */ /*

FernandoArielBeunza79156

697

Tesis de Grado en Ingeniera Informtica


Funcin int0: Redirecciona la interrupcin 0. */ extern void int0(void) __interrupt 0 __naked; /* Funcin int1: Redirecciona la interrupcin 1. */ extern void int1(void) __interrupt 1 __naked; /* Funcin int2: Redirecciona la interrupcin 2. */ extern void int2(void) __interrupt 2 __naked; /* Funcin int3: Redirecciona la interrupcin 3. */ extern void int3(void) __interrupt 3 __naked; /* Funcin int4: Redirecciona la interrupcin 4. */ extern void int4(void) __interrupt 4 __naked; /* Funcin int5: Redirecciona la interrupcin 5. */ extern void int5(void) __interrupt 5 __naked;

#endif

C.7.7. Archivo interrupts.c


/* interrupts.c: Implementacin de redirecciones de interrupcin. */

/* Archivos includos necesarios. */ #include "config.h"

/* Implementacin de funciones pblicas. */ /* Funcin int0: Redirecciona la interrupcin 0. */ void int0(void) __interrupt 0 __naked { __asm ljmp START_FIRMWARE+0x0003 __endasm; } /* Funcin int1: Redirecciona la interrupcin 1. */ void int1(void) __interrupt 1 __naked { __asm ljmp START_FIRMWARE+0x000b __endasm;

698

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


} /* Funcin int2: Redirecciona la interrupcin 2. */ void int2(void) __interrupt 2 __naked { __asm ljmp START_FIRMWARE+0x0013 __endasm; } /* Funcin int3: Redirecciona la interrupcin 3. */ void int3(void) __interrupt 3 __naked { __asm ljmp START_FIRMWARE+0x001b __endasm; } /* Funcin int4: Redirecciona la interrupcin 4. */ void int4(void) __interrupt 4 __naked { __asm ljmp START_FIRMWARE+0x0023 __endasm; } /* Funcin int5: Redirecciona la interrupcin 5. */ void int5(void) __interrupt 5 __naked { __asm ljmp START_FIRMWARE+0x002b __endasm; }

C.7.8. Archivo memory.h


/* memory.h: Declaracin de funciones referentes al manejo de la memoria destinada al firmware del modem PLC. */

#if !defined(__MEMORY_H__) #define __MEMORY_H__

/* Declaracin de funciones pblicas. */ /* Funcin init: Inicia la ejecucin del firmware del modem PLC. */ void init(void); /* Funcin erase: Borra la memoria destinada al firmware del modem PLC. */ void erase(void); /* Funcin read: Lee la memoria que contiene el firmware del modem PLC.

FernandoArielBeunza79156

699

Tesis de Grado en Ingeniera Informtica


*/ void read(void); /* Funcin write: Escribe en la memoria el firmware del modem PLC. */ void write(void); /* Funcin verify: Verifica el contenido del rea de memoria destinada al firmware del modem PLC. */ void verify(void); /* Funcin test: Evala el funcionamiento de banco de memoria del modem PLC. */ void test(void);

#endif

C.7.9. Archivo memory.c


/* memory.c: Implementacin de funciones referentes al manejo de la memoria destinada al firmware del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdio.h> #include <at89x52.h> #include "serial.h" #include "common.h"

/* Definicin de SFR necesarias. */ __sfr __at (0xa7) WDTPRG; __sfr __at (0xa6) WDTRST;

/* Configuracin del watchdog. */ /* Control del watchdog. */

/* Declaracin de funciones privadas. */ static int writemem(unsigned short int, unsigned char); static unsigned char hex2val(char *); static static void write_verify(int);

/* Implementacin de funciones pblicas. */ /* Funcin init: Inicia la ejecucin del firmware del modem PLC. */ void init(void) { /* Activa el watchdog. */ init_watchdog(1); /* Salta al rea de memoria donde se encuentra almacenado el firmware del modem PLC. */ __asm ljmp START_FIRMWARE __endasm; }

700

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Funcin erase: Borra la memoria destinada al firmware del modem PLC. */ void erase(void) { /* Variables. */ unsigned short int address;

/* Posicin de memoria. */

/* Borra la memoria donde se almacena el firmware del modem PLC. */ address = START_FIRMWARE; while(1) { /* Devuelve el estado de la operacin de borrado. */ if ((address == START_FIRMWARE) || (!(address % 0x10))) printf("%04X - %04X\r\n", address, (address + 0x0f)); /* Borra la posicin de memoria. */ if (!writemem(address, 0x00)) { printf("Error at %04X\r\n", address); return; } /* Verifica si se borraron todas las posiciones de memoria. */ if (address == END_FIRMWARE) break; address ++; } } /* Funcin read: Lee la memoria que contiene el firmware del modem PLC. */ void read(void) { /* Variables. */ unsigned short int rbytes; unsigned short int toread; unsigned short int address; unsigned char j; unsigned char checksum;

/* Cantidad de bytes a leer por registro. */ /* Cantidad de bytes a leer en total. */ /* Posicin de memoria. */ /* Contador de bytes ledos. */ /* Suma de verificacin. */

/* Lee el contenido de la memoria que contiene el firmware del modem PLC. */ toread = END_FIRMWARE - START_FIRMWARE; address = START_FIRMWARE; do { /* Calcula la cantidad de bytes a leer. */ if (toread > RECORD_SIZE) { rbytes = RECORD_SIZE; toread -= RECORD_SIZE; } else { rbytes = toread + 1; toread = 0; } /* Inicializa el clculo de la suma de verificacin. */ checksum = rbytes; checksum += (unsigned char) (address >> 8); checksum += (unsigned char) (address & 0xff);

FernandoArielBeunza79156

701

Tesis de Grado en Ingeniera Informtica


/* Devuelve el contenido de la memoria en formato hexadecimal Intel. */ printf(":%02X%04X00", rbytes, address); for(j = 0; j < rbytes; j++) { checksum += *((__xdata unsigned char *) address); printf("%02X", *((__xdata unsigned char *) address)); address ++; } checksum = ((checksum ^ 0xff) + 1) & 0xff; printf("%02X\r\n", checksum); } while(toread); printf(":00000001FF\r\n"); } /* Funcin write: Escribe en la memoria el firmware del modem PLC. */ void write(void) { write_verify(1); } /* Funcin verify: Verifica el contenido del rea de memoria destinada al firmware del modem PLC. */ void verify(void) { write_verify(0); } /* Funcin test: Evala el funcionamiento de banco de memoria del modem PLC. */ void test(void) { /* Variables. */ unsigned short int errors; unsigned short int address; unsigned char dat; unsigned char read;

/* Cantidad de errores encontrados. */ /* Posicin de memoria. */ /* Dato original de la posicin de memoria. */ /* Dato ledo de la posicin de memoria. */

/* Evala el funcionamiento de banco de memoria del modem PLC. */ errors = 0; address = START_DATA; while(1) { /* Lee el dato almacenado. */ dat = *((__xdata unsigned char *) address); /* Escribe todos los bits con valor 0. */ writemem(address, 0x00); read = *((__xdata unsigned char *) address); if (read != 0x00) { printf("Error at %04X: write 00 read %02X\r\n", address, read); errors ++; } /* Escribe todos los bits con valor 1. */ writemem(address, 0xff); read = *((__xdata unsigned char *) address); if (read != 0xff) {

702

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


printf("Error at %04X: write FF read %02X\r\n", address, read); errors ++; } /* Restaura el dato almacenado originalmente. */ writemem(address, dat); read = *((__xdata unsigned char *) address); if (read != dat) { printf("Error at %04X: write %02X read %02X\r\n", address, dat, read); errors ++; } else printf("%04X: OK\r\n", address); /* Verifica si evalu todas las posiciones de memoria. */ if (address == END_FIRMWARE) break; address ++; } /* Devuelve el resultado de la operacin. */ if (errors) printf("%i error(s)\r\n", errors); }

/* Implementacin de funciones privadas. */ /* Funcin writemem: Modifica el contenido de la posicin de memoria especificada. */ static int writemem(unsigned short int addr, unsigned char dat) { /* Varaibles. */ unsigned int i; /* Contador. */ unsigned short int j; /* Contador. */

/* Modifica el contenido de la memoria. */ *((__xdata unsigned char *) addr) = dat; for(i = 0; i < 0x20; i++) { for(j = 0; j < 0x4000; j++) { if (*((__xdata unsigned char *) addr) == dat) return 1; } } return 1; } /* Funcin hex2val: Convierte una cadena de caracteres que contiene un nmero hexadecimal de dos digitos en su correspondiente valor numrico entre 0 y 255. */ static unsigned char { /* Variables. char d; unsigned char unsigned char hex2val(char *v) */ i; val; /* Dgito. */ /* Cantidad de digitos. */ /* Valor numrico. */

/* Convierte cada digito hexadecimal en su correspondiente valor. */ val = 0; for(i = 0; i < 2; i++) { #if defined SDCC_MODEL_SMALL d = *((__data char *) (v + i)); #elif (defined SDCC_MODEL_LARGE) || (defined SDCC_MODEL_MEDIUM)

FernandoArielBeunza79156

703

Tesis de Grado en Ingeniera Informtica


d = *((__xdata char *) (v + i)); #else #error "hex2val(): unknow memory model" #endif val <<= 4; if ((d >= '0') && (d <= '9')) val += d - '0'; else if ((d >= 'a') && (d <= 'f')) val += d - 'a' + 0x0a; else if ((d >= 'A') && (d <= 'F')) val += d - 'A' + 0x0a; else { val = 0; break; } } /* Devuelve el valor nmerico obtenido. */ return val; } /* Funcin write_verify: Escribe o verifica la memoria que contiene el firmware del modem PLC. */ static void write_verify(int op) { /* Variables. */ short int errors; unsigned short int address; length_t length; unsigned char i; unsigned char val; unsigned char lstr; unsigned char type; char *ptr; char *ptr2; unsigned char checksum; char str[(RECORD_SIZE * 2) + 12];

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

Contador de errores. */ Direccin de memoria. */ Tamao del registro. */ Nmero de bytes del registro. */ Valor ledo. */ Longitud de la cadena ingresada. */ Tipo de registro. */ Puntero a registro. */ Puntero a registro. */ Suma de verificacin. */ Registro recibido. */

/* Procesa cada registro recibido. */ errors = 0; while(1) { /* Lee un registro. */ printf(">"); gets(str); /* Verifica si el registro se encuentra vaca. */ if (streq(str, "")) continue; /* Verifica que el registro corresponda al formato hexadecimal Intel. */ lstr = strlen1(str); if (lstr < 11) { printf("Invalid record\r\n\n"); continue; } if (!(lstr & 0x01)) { printf("Invalid record\r\n\n"); continue; } if (*str != ':') { printf("Invalid record\r\n\n"); continue;

704

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


} /* Obtiene la cantidad de bytes que tiene el registro. */ ptr = str + 1; val = hex2val(ptr); ptr += 2; length = val; checksum = val; /* Verifica que la cantidad de bytes que contiene el registro sea vlida. */ if (length > RECORD_SIZE) { printf("Invalid record\r\n\n"); continue; } /* Obtiene la posicin de memoria. */ val = hex2val(ptr); ptr += 2; address = val; address <<= 8; checksum += val; val = hex2val(ptr); ptr += 2; address |= val; checksum += val; /* Obtiene el tipo de registro. */ val = hex2val(ptr); ptr += 2; type = val; checksum += val; /* Verifica si es el registro fin. */ if (type == 0x01) break; /* Verifica que el tipo de registro sea vlido. */ if ((type != 0x00) && (type != 0x01)) { printf("Invalid record\r\n\n"); continue; } /* Obtiene los bytes a escribir o verificar. */ ptr2 = ptr; for(i = 0; i < length; i++) { val = hex2val(ptr); ptr += 2; checksum += val; } /* Verifica la suma de verificacin. */ checksum += hex2val(ptr); ptr += 2; if (checksum) { printf("Checksum error\r\n\n"); continue; } /* Escribe o verifica cada byte del registro. */ for(i = 0; i < length; i++) { /* Verifica que la posicin de memoria sea vlida. */ if ((((unsigned long int) address) < ((unsigned long int) START_FIRMWARE)) || (((unsigned long int) address) > ((unsigned long int) END_FIRMWARE))) {

FernandoArielBeunza79156

705

Tesis de Grado en Ingeniera Informtica


printf("Invalid address\r\n\n"); continue; } /* Escribe un byte del registro. */ val = hex2val(ptr2); ptr2 += 2; if (op) writemem(address, val); /* Verifica un byte del registro. */ if (*((__xdata unsigned char *) address) != val) { printf("Error at %04X\r\n", address); errors ++; } /* Actualiza la posicin de memoria. */ address ++; } }; /* Devuelve el resultado de la operacin. */ if (errors) printf("%i error(s)\r\n", errors); }

C.7.10. Archivo boot.c


/* boot.c: Cargador del firmware del modem PLC. */

/* Archivos includos necesarios. */ #include "config.h" #include <stdio.h> #include <at89x52.h> #include "memory.h" #include "interrupts.h" #include "serial.h" #include "common.h"

/* Funcin main: Funcin principal. */ void main(void) { char str[LINE_SIZE];

/* Lnea de comandos. */

/* Inicializacin del microcontrolador. */ cli(); initports(); inituart(0xff); init_watchdog(0); /* Recibe de comandos recibidos por medio de la UART. */ printf("Modem PLC boot\r\n\n"); while(1) { /* Lee la lnea de comandos. */ printf("#"); gets(str); /* Verifica si la lnea de comandos se encuentra vaca. */ if (strceq(str, "")) continue;

706

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Verifica si el comando recibido corresponde ejecucin del firmware del modem PLC. */ if (strceq(str, "init")) { printf("OK\r\n\n"); init(); continue; } /* Verifica si el comando recibido corresponde del cargador del firmware del modem PLC. */ else if (strceq(str, "reset")) { printf("OK\r\n\n"); reset(); continue; } /* Verifica si el comando recibido corresponde del modem PLC. */ else if (strceq(str, "erase")) erase(); /* Verifica si el comando recibido corresponde firmware del modem PLC. */ else if (strceq(str, "read")) read(); /* Verifica si el comando recibido corresponde firmware del modem PLC.*/ else if (strceq(str, "write")) write(); /* Verifica si el comando recibido corresponde firmware del modem PLC. */ else if (strceq(str, "verify")) verify(); /* Verifica si el comando recibido corresponde memoria. */ else if (strceq(str, "test")) test(); else printf("Invalid command\r\n"); printf("OK\r\n"); } } al inicio de la

a la reinicializacin

al borrado del firmware

a la lectura del

a la escritura del

a la verificacin del

a la prueba del banco de

C.8. Especificacin del cdigo fuente comn utilizado por el firmware del modem PLC y el firmware cargador
En esta seccin se detalla el cdigo fuente comn utilizado por el firmware del modem PLC y el firmware del cargador compuesto por los siguientes archivos:

Archivo common.h: en este archivo se declaran primitivas con funcionalidades generales. Archivo common.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo common.h. Archivo serial.h: en este archivo se declaran primitivas con funcionalidades referentes a la entrada y salida va puerto RS232.

FernandoArielBeunza79156

707

Tesis de Grado en Ingeniera Informtica

Archivo serial.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo serial.c.

C.8.1. Archivo common.h


/* common.h: Declaracin de funciones comunes. */

#if !defined(__COMMON_H__) #define __COMMON_H__

/* Archivos includos necesarios. */ #include <stdlib.h>

/* Definicin de tipos. */ /* Tipo longitud. */ typedef short int length_t;

/* Definicin de funciones pblicas. */ /* Funcin usl2b: Convierte un entero sin signo de 16 bits codificado little endian en otro codificado en big endian. */ unsigned short int usl2b(unsigned short int); /* Funcin usb2l: Convierte un entero sin signo de 16 bits codificado big endian en otro codificado en little endian. */ #define usb2l(val)\ usl2b(val) /* Funcin getfcs: Calcula la suma de verificacin. */ unsigned short int getfcs(const void *, length_t); /* Funcin memcpy1: Copia el contenido de la memoria de datos. */ void memcpy1(void *, const void *, length_t); /* Funcin memccpy1: Copia el contenido de la memoria de cdigo a la memoria de datos. */ void memccpy1(void *, const void *, length_t); /* Funcin memcpy2: Copia el contenido de la memoria de datos. */ void memcpy2(void *, length_t, const void *, length_t); /*

708

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Funcin memccpy2: Copia el contenido de la memoria de datos. */ void memccpy2(void *, length_t, const void *, length_t); /* Funcin memcmp1: Compara el contenido de la memoria de datos. */ int memcmp1(const void *, const void *, length_t); /* Funcin memccmp1: Compara el contenido de la memoria de cdigo a la memoria de datos. */ int memccmp1(const void *, const void *, length_t); /* Funcin streq: Verifica si dos cadenas de caracteres en memoria de datos son iguales. */ int streq(const char *, const char *); /* Funcin strceq: Verifica si una cadena de caracteres en memoria de datos y una cadena de caracteres en memoria de cdigo son iguales. */ int strceq(const char *, const char *); /* Funcin strlen1: Devuelve la longitud de una cadena de caracteres en memoria de datos. */ length_t strlen1(const char *); /* Funcin strlen1: Devuelve la longitud de una cadena de caracteres en memoria de cdigo. */ length_t strclen1(const char *); /* Funcin sei: Activa interrupciones. */ #define sei()\ __asm setb EA __endasm /* Funcin cli: Desactiva interrupciones. */ #define cli()\ __asm clr EA __endasm /* Funcin reset: Reinicia la ejecucin del cargador de firmware del modem PLC. */ void reset(void); /* Funcin initports: Inicializa los puertos. */ void initports(void); /* Funcin idle: Detiene la ejecucin del firmware del modem PLC.

FernandoArielBeunza79156

709

Tesis de Grado en Ingeniera Informtica


*/ #define idle()\ PCON |= 0x01 /* Funcin init_watchdog: Inicializa el watchdog del microcontrolador. */ void init_watchdog(unsigned char); /* Funcin reset_watchdog: Reinicia el watchdog del microcontrolador. */ void reset_watchdog(void); /* Funcin status_watchdog: Devuelve el estado del watchdog del microcontrolador. */ unsigned char status_watchdog(void);

#endif

C.8.2. Archivo common.c


/* common.c: Implementacin de funciones comunes. */

/* Archivos includos necesarios. */ #include <string.h> #include <stdlib.h> #include "common.h"

/* Definicin de SFR necesarias. */ __sfr __at (0xa7) WDTPRG; __sfr __at (0xa6) WDTRST;

/* Configuracin del watchdog. */ /* Control del watchdog. */

/* Definicin de constantes. */ #define WATCHDOG_PERIOD /* Variables globales. */ /* Estado del watchdog. */ static unsigned char __wdt_status__;

0x000f

/* Declaracin de funciones privadas. */ static unsigned short int crc16_update(unsigned short int, unsigned char); static void memcpy3(unsigned char *, length_t, const unsigned char *, length_t); static void memccpy3(unsigned char *, length_t, const unsigned char *, length_t); static int memcmp2(const unsigned char *, const unsigned char *, length_t); static int memccmp2(const unsigned char *, const unsigned char *, length_t);

/* Implementacin de funciones pblicas. */ /* Funcin usl2b: Convierte un entero sin signo de 16 bits codificado little endian en otro

710

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


codificado en big endian. */ unsigned short int usl2b(unsigned short int val) { return (val << 8) | (val >> 8); } /* Funcin getfcs: Calcula la suma de verificacin. */ unsigned short int getfcs(const void *dat, length_t len) { /* Variables. */ unsigned short int fcs; unsigned char *ptr;

/* Suma de verificacin. */ /* Puntero a los datos. */

/* Calcula la suma de verificacin. */ fcs = 0; ptr = (unsigned char *) dat; #if defined SDCC_MODEL_SMALL while(len--) { fcs = crc16_update(fcs, *((__data unsigned char *) (ptr++))); reset_watchdog(); } #elif (defined SDCC_MODEL_LARGE) || (defined SDCC_MODEL_MEDIUM) while(len--) { fcs = crc16_update(fcs, *((__xdata unsigned char *) (ptr++))); reset_watchdog(); } #else #error "getfcs(): unknow memory model" #endif /* Devuelve la suma de verificacin. */ return fcs; } /* Funcin memcpy1: Copia el contenido de la memoria de datos. */ void memcpy1(void *dest, const void *src, length_t ssrc) { memcpy2(dest, ssrc, src, ssrc); } /* Funcin memccpy1: Copia el contenido de la memoria de cdigo a la memoria de datos. */ void memccpy1(void *dest, const void *src, length_t ssrc) { memccpy2(dest, ssrc, src, ssrc); } /* Funcin memcpy2: Copia el contenido de la memoria de datos. */ void memcpy2(void *dest, length_t sdest, const void *src, length_t ssrc) { memcpy3(dest, sdest, src, ssrc); } /* Funcin memccpy2: Copia el contenido de la memoria de cdigo a la memoria de datos.

FernandoArielBeunza79156

711

Tesis de Grado en Ingeniera Informtica


*/ void memccpy2(void *dest, length_t sdest, const void *src, length_t ssrc) { memccpy3(dest, sdest, src, ssrc); } /* Funcin memcmp1: Compara el contenido de la memoria de datos. */ int memcmp1(const void *mem1, const void *mem2, length_t size) { return memcmp2(mem1, mem2, size); } /* Funcin memccmp1: Compara el contenido de la memoria de cdigo a la memoria de datos. */ int memccmp1(const void *mem1, const void *mem2, length_t size) { return memccmp2(mem1, mem2, size); } /* Funcin streq: Verifica si dos cadenas de caracteres en memoria de datos son iguales. */ int streq(const char *str1, const char *str2) { /* Variables. */ int result; length_t i; char b1; char b2;

/* /* /* /*

Resultado de la comparacin. */ Contador. */ Caracter de la primer cadena. */ Caracter de la segunda cadena. */

/* Compara ambas cadenas de caracteres. */ result = 0; for(i = 0;; i++) { #if defined SDCC_MODEL_SMALL b1 = *((__data char *) (str1 + i)); b2 = *((__data char *) (str2 + i)); #elif (defined SDCC_MODEL_LARGE) || (defined SDCC_MODEL_MEDIUM) b1 = *((__xdata char *) (str1 + i)); b2 = *((__xdata char *) (str2 + i)); #else #error "streq(): unknow memory model" #endif if (!(i & WATCHDOG_PERIOD)) reset_watchdog(); if ((b1 == 0) && (b2 == 0)) { result = 1; break; } if ((b1 == 0) || (b2 == 0)) break; if (b1 != b2) break; } reset_watchdog(); return result; } /* Funcin strceq: Verifica si una cadena de caracteres en memoria de datos y una cadena de caracteres en memoria de cdigo son iguales. */ int strceq(const char *strd, const char *strc) {

712

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Variables. */ int result; char bd; char bc; length_t i; /* Resultado de la comparacin. */ /* Caracter de la cadena en memoria de datos. */ /* Caracter de la cadena en memoria de cdigo. */ /* Contador. */

/* Compara ambas cadenas de caracteres. */ result = 0; for(i = 0;; i++) { #if defined SDCC_MODEL_SMALL bd = *((__data char *) (strd + i)); bc = *((__code char *) (strc + i)); #elif (defined SDCC_MODEL_LARGE) || (defined SDCC_MODEL_MEDIUM) bd = *((__xdata char *) (strd + i)); bc = *((__code char *) (strc + i)); #else #error "strceq(): unknow memory model" #endif if (!(i & WATCHDOG_PERIOD)) reset_watchdog(); if ((bd == 0) && (bc == 0)) { result = 1; break; } if ((bd == 0) || (bc == 0)) break; if (bd != bc) break; } reset_watchdog(); return result; } /* Funcin strlen1: Devuelve la longitud de una cadena de caracteres en memoria de datos. */ length_t strlen1(const char *str) { /* Variables. */ length_t len;

/* Longitud de la cadena de caracteres. */

/* Obtiene la longitud de la cadena de caracteres. */ len = 0; #if defined SDCC_MODEL_SMALL while(*((__data char *) (str + len)) != 0) { if (!(len & WATCHDOG_PERIOD)) reset_watchdog(); len ++; } reset_watchdog(); #elif (defined SDCC_MODEL_LARGE) || (defined SDCC_MODEL_MEDIUM) while(*((__xdata char *) (str + len)) != 0) { if (!(len & WATCHDOG_PERIOD)) reset_watchdog(); len ++; } reset_watchdog(); #else #error "strlen1(): unknow memory model" #endif /* Devuelve la longitud de la cadena de caracteres. */ return len; } /*

FernandoArielBeunza79156

713

Tesis de Grado en Ingeniera Informtica


Funcin strlen1: Devuelve la longitud de una cadena de caracteres en memoria de cdigo. */ length_t strclen1(const char *str) { /* Variables. */ length_t len;

/* Longitud de la cadena de caracteres. */

/* Obtiene la longitud de la cadena de caracteres. */ len = 0; while(*((__code char *) (str + len)) != 0) { len ++; if (!(len & WATCHDOG_PERIOD)) reset_watchdog(); } /* Devuelve la longitud de la cadena de caracteres. */ return len; } /* Funcin reset: Reinicia la ejecucin del cargador de firmware del modem PLC. */ void reset(void) { init_watchdog(1); while(1); } /* Funcin initports: Inicializa los puertos. */ void initports(void) { __asm mov mov mov mov __endasm; } /* Funcin init_watchdog: Inicializa el watchdog del microcontrolador. */ void init_watchdog(unsigned char s) { if (!s) { __wdt_status__ = 0; return; } __wdt_status__ = 1; __asm push IE clr EA orl _WDTPRG, #0x07 mov _WDTRST, #0x1e mov _WDTRST, #0xe1 pop IE __endasm; } /* Funcin reset_watchdog: Reinicia el watchdog del microcontrolador. p0, p1, p2, p3, #0xff #0xff #0xff #0xff ; ; ; ;

; ; ; ; ; ;

714

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


*/ void reset_watchdog(void) { if (!__wdt_status__) return; __asm push IE clr EA mov _WDTRST, #0x1e mov _WDTRST, #0xe1 pop IE __endasm; } /* Funcin status_watchdog: Devuelve el estado del watchdog del microcontrolador. */ unsigned char status_watchdog(void) { if (__wdt_status__) return 1; return 0; }

; ; ; ; ;

/* Implementacin de funciones privadas. */ /* Funcin crc16_update: Calcula el CRC-16. */ static unsigned short int crc16_update(unsigned short int crc, unsigned char a) { /* Variables. */ int i; /* Contador. */

/* Calcula el CRC-16. */ crc ^= a; for (i = 0; i < 8; i++) { if (crc & 1) crc = (crc >> 1) ^ 0xA001; else crc = (crc >> 1); } /* Devuelve el CRC-16. */ return crc; } /* Funcin memcpy3: Copia el contenido de la memoria de datos. */ void memcpy3(unsigned char *dest, length_t sdest, const unsigned char *src, length_t ssrc) { /* Variables. */ length_t i; /* Contador. */

/* Copia el contenido de la memoria. */ if (sdest > ssrc) sdest = ssrc; #if defined SDCC_MODEL_SMALL for(i = 0; i < sdest; i++) { if (!(i & WATCHDOG_PERIOD)) reset_watchdog(); *((__data unsigned char *) (dest + i)) = *((__data unsigned char *) (src + i)); } reset_watchdog();

FernandoArielBeunza79156

715

Tesis de Grado en Ingeniera Informtica


#elif (defined SDCC_MODEL_LARGE) || (defined SDCC_MODEL_MEDIUM) for(i = 0; i < sdest; i++) { if (!(i & WATCHDOG_PERIOD)) reset_watchdog(); *((__xdata unsigned char *) (dest + i)) = *((__xdata unsigned char *) (src + i)); } reset_watchdog(); #else #error "memcpy3(): unknow memory model" #endif } /* Funcin memccpy3: Copia el contenido de la memoria de cdigo a la memoria de datos. */ static void memccpy3(unsigned char *dest, length_t sdest, const unsigned char *src, length_t ssrc) { /* Variables. */ length_t i; /* Contador. */

/* Copia el contenido de la memoria. */ if (sdest > ssrc) sdest = ssrc; #if defined SDCC_MODEL_SMALL for(i = 0; i < sdest; i++) { if (!(i & WATCHDOG_PERIOD)) reset_watchdog(); *((__data unsigned char *) (dest + i)) = *((__code unsigned char *) (src + i)); } reset_watchdog(); #elif (defined SDCC_MODEL_LARGE) || (defined SDCC_MODEL_MEDIUM) for(i = 0; i < sdest; i++) { if (!(i & WATCHDOG_PERIOD)) reset_watchdog(); *((__xdata unsigned char *) (dest + i)) = *((__code unsigned char *) (src + i)); } reset_watchdog(); #else #error "memccpy3(): unknow memory model" #endif } /* Funcin memcmp2: Compara el contenido de la memoria de datos. */ static int memcmp2(const unsigned char *mem1, const unsigned char *mem2, length_t size) { /* Variables. */ length_t i; /* Contador. */

/* Copia el contenido de la memoria. */ #if defined SDCC_MODEL_SMALL for(i = 0; i < size; i++) { if (!(i & WATCHDOG_PERIOD)) reset_watchdog(); if (*((__data unsigned char *) (mem1 + i)) != *((__data unsigned char *) (mem2 + i))) return 0; } reset_watchdog(); return 1; #elif (defined SDCC_MODEL_LARGE) || (defined SDCC_MODEL_MEDIUM) for(i = 0; i < size; i++)

716

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


{ if (!(i & WATCHDOG_PERIOD)) reset_watchdog(); if (*((__xdata unsigned char *) (mem1 + i)) != *((__xdata unsigned char *) (mem2 + i))) return 0; } reset_watchdog(); return 1; #else #error "memcmp2(): unknow memory model" #endif } /* Funcin memccmp2: Compara el contenido de la memoria de cdigo a la memoria de datos. */ static int memccmp2(const unsigned char *mem1, const unsigned char *mem2, length_t size) { /* Variables. */ length_t i; /* Contador. */

/* Copia el contenido de la memoria. */ #if defined SDCC_MODEL_SMALL for(i = 0; i < size; i++) { if (!(i & WATCHDOG_PERIOD)) reset_watchdog(); if (*((__data unsigned char *) (mem1 + i)) != *((__code unsigned char *) (mem2 + i))) return 0; } reset_watchdog(); return 1; #elif (defined SDCC_MODEL_LARGE) || (defined SDCC_MODEL_MEDIUM) for(i = 0; i < size; i++) { if (!(i & WATCHDOG_PERIOD)) reset_watchdog(); if (*((__xdata unsigned char *) (mem1 + i)) != *((__code unsigned char *) (mem2 + i))) return 0; } reset_watchdog(); return 1; #else #error "memccmp2(): unknow memory model" #endif }

C.8.3. Archivo serial.h


/* serial.h: Declaracin de funciones referentes a la UART. */

#if !defined(__SERIAL_H__) #define __SERIAL_H__

/* Definicin de funciones pblicas. */ /* Funcin inituart: Inicializa la UART del microcontrolador. */

FernandoArielBeunza79156

717

Tesis de Grado en Ingeniera Informtica


void inituart(unsigned char); /* Funcin putchar: Enva un caracter a travs de la UART. */ void putchar(char); /* Funcin poll: Devuelve si hay un caracter almacenado en la UART. */ int poll(void); /* Funcin getchar: Devuelve un caracter recibido por medio de la UART. */ char getchar(void);

#endif

C.8.4. Archivo serial.c


/* serial.c: Implementacin de funciones referentes a la UART. */

/* Archivos includos necesarios. */ #include "common.h"

/* Definicin de SFR necesarias. */ __sfr __at (0x87) SIO_PCON; __sfr __at (0x89) SIO_TMOD; __sfr __at (0x8D) SIO_TH1; __sfr __at (0x8B) SIO_TL1; __sfr __at (0x98) SIO_SCON; __sfr __at (0x99) SIO_SBUF; __sbit __at (0x8E) SIO_TR1; __sbit __at (0x98) SIO_RI; __sbit __at (0x99) SIO_TI; __sbit __at (0x9A) SIO_RB8; __sbit __at (0x9B) SIO_TB8; __sbit __at (0x9C) SIO_REN; __sbit __at (0x9D) SIO_SM2; __sbit __at (0x9E) SIO_SM1; __sbit __at (0x9F) SIO_SM0;

/* Variables globales. */ /* Contador de reinicio del watchdog. */ static unsigned char __watchdog_counter__;

/* Funcin inituart: Inicializa la UART del microcontrolador. */ void inituart(unsigned char t1_reload) { /* Inicializa la UART. */ SIO_SCON = 0x50; SIO_TR1 = 0;

718

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


SIO_TMOD = (SIO_TMOD & 0x0f) | 0x20; SIO_PCON |= 0x80; SIO_TH1 = t1_reload; SIO_TR1 = 1; SIO_TI = 1; /* Inicializa el contador de reinicio del watchdog. */ __watchdog_counter__ = 0; } /* Funcin putchar: Enva un caracter a travs de la UART. */ void putchar(char c) { if ((status_watchdog()) && (!__watchdog_counter__)) { reset_watchdog(); while(!SIO_TI); } else while(!SIO_TI); SIO_TI = 0; SIO_SBUF = c; __watchdog_counter__ ++; } /* Funcin poll: Devuelve si hay un caracter almacenado en la UART. */ int poll(void) { return SIO_RI; } /* Funcin getchar: Devuelve un caracter recibido por medio de la UART. */ char getchar(void) { /* Varaibles. */ char c;

/* Caracter recibido. */

/* Recibe un caracter por medio de la UART. */ if (status_watchdog()) { while(!poll()) reset_watchdog(); } else while(!poll()); SIO_RI = 0; c = SIO_SBUF; /* Devuelve el caracter recibido. */ return c; }

FernandoArielBeunza79156

719

Tesis de Grado en Ingeniera Informtica

720

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Apndice D: Interfaz C++


En el presente apndice se detalla la interfaz C++ constituida por una biblioteca de clases. Junto con la declaracin de las clases se especifica el cdigo fuente que implementa cada uno de los mtodos pertenecientes a las clases mencionadas.

D.1. Descripcin
La interfaz C++ es una extensin de la capa de aplicacin que permite proveer a las aplicaciones orientadas a objetos desarrolladas en lenguaje C++, los mismos servicios brindados a aplicaciones escritas en lenguaje C. El sistema se encuentra desarrollado en lenguaje C, ya que permite implementar los distintos componentes del sistema de comunicaciones en diversas plataformas de forma eficiente. De todas formas, el sistema se encuentra diseado para aceptar el agregado de interfaces que permitan adaptar la interfaz de la capa de aplicacin a otros entornos y lenguajes de programacin. En ste caso se hace referencia al lenguaje C++, porque es el implementado en el presente trabajo, y utilizado para mostrar la caracterstica anterior de diseo, pero nada impide que en un futuro se desarrollen extensiones a otros lenguajes. La interfaz se encuentra desarrollada tanto para Windows como para Linux, del mismo modo que las capas de aplicacin y presentacin. No se encuentra desarrollada una plataforma para AT89X5X ya que resulta poco prctica para el microcontrolador propuesto para el dispositivo cliente, pero nada impide que en el futuro tambin se desarrolle una interfaz C++ para determinados tipos de microcontroladores cuyo poder de computo absorban el costo adicional de C++.

D.2. Cdigo fuente


La interfaz C++ se compone de dos clases asociadas a los tipos de datos estructurados ofrecidos por la interfaz de la capa de aplicacin. Una de las clases se encarga del manejo de la conexin, mientras que la otra maneja los mensajes que se enva y reciben. La interfaz permite adaptar, la interfaz de la capa de aplicacin provista por el sistema de comunicaciones, al modelo de objetos del lenguaje C++, para que aplicaciones desarrolladas en el lenguaje anterior puedan tambin utilizar los servicios provistos por el sistema desarrollado en ste trabajo. A continuacin se presenta el cdigo fuente asociado a la interfaz C++ para plataforma Windows y Linux.

D.2.1. Archivo modplcapcpp.h (plataforma Windows)


/* modplcapcpp.h: Declaracin de funciones referentes a la interfaz de la capa de aplicacin del modem PLC. */

#if !defined(__MODPLCAPCPP_H__) #define __MODPLCAPCPP_H__

/* Archivos includos necesarios. */

FernandoArielBeunza79156

721

Tesis de Grado en Ingeniera Informtica


#include "..\modplcap\modplcap.h"

/* Definicin de tipos. */ /* Identificador de grupo. */ typedef unsigned char modplcapcpp_grpid; /* Identificador de mensaje. */ typedef unsigned short int modplcapcpp_msgid; /* Tipo de campo. */ typedef unsigned char modplcapcpp_ftype;

/* Definicin de constantes. */ /* Tipos de datos. */ #define MODPLCAPCPP_NULLTYPE #define MODPLCAPCPP_CHARTYPE #define MODPLCAPCPP_SINT8TYPE #define MODPLCAPCPP_UINT8TYPE #define MODPLCAPCPP_SINT16TYPE #define MODPLCAPCPP_UINT16TYPE #define MODPLCAPCPP_SINT32TYPE #define MODPLCAPCPP_UINT32TYPE #define MODPLCAPCPP_FLOATTYPE

MODPLCAP_NULLTYPE MODPLCAP_CHARTYPE MODPLCAP_SINT8TYPE MODPLCAP_UINT8TYPE MODPLCAP_SINT16TYPE MODPLCAP_UINT16TYPE MODPLCAP_SINT32TYPE MODPLCAP_UINT32TYPE MODPLCAP_FLOATTYPE

/* Variables globales. */ /* Indicador de carga de biblioteca dinmica. */ int __modplcapcpp_loadlib__ = 0;

/* Declaracin de clases. */ /* Clases declaradas. */ class modplcapcpp; class modplcapcpp_msg; /* Clase modplcapcpp */ class modplcapcpp { /* Atributos y mtodos privados. */ private: modplcap_hd *handle;

/* Manejador de capa de aplicacin. */

/* Mtodos pblicos. */ public: /* Constructor: Inicializa los recursos utilizados por la capa de aplicacin del modem PLC. */ modplcapcpp(int); /* Destructor: Libera los recursos utilizados por la capa de aplicacin del modem PLC. */ ~modplcapcpp(); /* Mtodo publish: Registra el dispositivo como publicador del grupo de difusin especificado.

722

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


*/ int publish(modplcapcpp_grpid); /* Mtodo subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ int subscribe(modplcapcpp_grpid); /* Mtodo leave: Desvincula el dispositivo del grupo de difusin especificado. */ int leave(modplcapcpp_grpid); /* Mtodo poll: Verifica la llegada de un nuevo mensaje. */ int poll(void); /* Mtodo status: Devuelve el estado del modem PLC. */ int status(void); /* Clases amigas. */ friend class modplcapcpp_msg; }; /* Clase modplcapcpp_msg */ class modplcapcpp_msg { /* Atributos y mtodos privados. */ private: modplcap_msg *msghd;

/* Manejador de mensaje. */

/* Mtodos pblicos. */ public: /* Constructor: Crea un nuevo mensaje. */ modplcapcpp_msg(modplcapcpp *, modplcapcpp_grpid, modplcapcpp_msgid); /* Constructor: Crea un copia de un mensaje. */ modplcapcpp_msg(modplcapcpp_msg *msg); /* Constructor: Recibe un mensaje por medio de la capa de aplicacin. */ modplcapcpp_msg(modplcapcpp *hd); /* Destructor: Destruye un mensaje. */ ~modplcapcpp_msg(); /* Mtodo putfield: Agrega un nuevo campo al mensaje. */

FernandoArielBeunza79156

723

Tesis de Grado en Ingeniera Informtica


int putfield(modplcapcpp_ftype, unsigned char, const void *); /* Mtodo sendmsg: Enva un mensaje por medio de la capa de aplicacin. */ int sendmsg(void); /* Mtodo getfield: Extrae un campo del mensaje. */ int getfield(modplcapcpp_ftype *, unsigned char *, void *); /* Mtodo getgrpid: Devuelve el identificador de grupo del mensaje. */ modplcapcpp_grpid getgrpid(void); /* Mtodo getmsgid: Devuelve el identificador de mensaje. */ modplcapcpp_msgid getmsgid(void); };

/* Implementacin de mtodos de la clase modplcapcpp. */ /* Constructor: Inicializa los recursos utilizados por la capa de aplicacin del modem PLC. */ inline modplcapcpp::modplcapcpp(int sid) { if (!__modplcapcpp_loadlib__) { modplcap_loadlib(); __modplcapcpp_loadlib__ = 1; } this->handle = modplcap_init(sid); } /* Destructor: Libera los recursos utilizados por la capa de aplicacin del modem PLC. */ inline modplcapcpp::~modplcapcpp() { modplcap_release(this->handle); } /* Mtodo publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ inline int modplcapcpp::publish(modplcapcpp_grpid grpid) { return modplcap_publish(this->handle, (modplcap_grpid)grpid); } /* Mtodo subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ inline int modplcapcpp::subscribe(modplcapcpp_grpid grpid) { return modplcap_subscribe(this->handle, (modplcap_grpid) grpid); }

724

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Mtodo leave: Desvincula el dispositivo del grupo de difusin especificado. */ inline int modplcapcpp::leave(modplcapcpp_grpid grpid) { return modplcap_leave(this->handle, (modplcap_grpid) grpid); } /* Mtodo poll: Verifica la llegada de un nuevo mensaje. */ inline int modplcapcpp::poll(void) { return modplcap_poll(this->handle); } /* Mtodo status: Devuelve el estado del modem PLC. */ inline int modplcapcpp::status(void) { return modplcap_status(this->handle); }

/* Implementacin de mtodos de la clase modplcapcpp_msg. */ /* Constructor: Crea un nuevo mensaje. */ inline modplcapcpp_msg::modplcapcpp_msg(modplcapcpp *hd, modplcapcpp_grpid grpid, modplcapcpp_msgid msgid) { if (!__modplcapcpp_loadlib__) { modplcap_loadlib(); __modplcapcpp_loadlib__ = 1; } this->msghd = new modplcap_msg; if (!this->msghd) return; modplcap_newmsg(hd->handle, (modplcap_msg *) (this->msghd), (modplcap_grpid) grpid, (modplcap_msgid) msgid); } /* Constructor: Crea un copia de un mensaje. */ inline modplcapcpp_msg::modplcapcpp_msg(modplcapcpp_msg *msg) { if (!__modplcapcpp_loadlib__) { modplcap_loadlib(); __modplcapcpp_loadlib__ = 1; } this->msghd = new modplcap_msg; if (!this->msghd) return; if (!modplcap_copymsg(this->msghd, msg->msghd)) delete this->msghd; } /* Constructor: Recibe un mensaje por medio de la capa de aplicacin. */ inline modplcapcpp_msg::modplcapcpp_msg(modplcapcpp *hd)

FernandoArielBeunza79156

725

Tesis de Grado en Ingeniera Informtica


{ if (!__modplcapcpp_loadlib__) { modplcap_loadlib(); __modplcapcpp_loadlib__ = 1; } this->msghd = new modplcap_msg; if (!this->msghd) return; if (!modplcap_receivemsg(hd->handle, this->msghd)) delete this->msghd; } /* Destructor: Destruye un mensaje. */ inline modplcapcpp_msg::~modplcapcpp_msg() { if (!this->msghd) return; modplcap_destroymsg(this->msghd); delete this->msghd; } /* Mtodo putfield: Agrega un nuevo campo al mensaje. */ inline int modplcapcpp_msg::putfield(modplcapcpp_ftype type, unsigned char count, const void *dat) { return modplcap_putfield(this->msghd, (modplcap_ftype) type, count, dat); } /* Mtodo sendmsg: Enva un mensaje por medio de la capa de aplicacin. */ inline int modplcapcpp_msg::sendmsg(void) { return modplcap_sendmsg(this->msghd); } /* Mtodo getfield: Extrae un campo del mensaje. */ inline int modplcapcpp_msg::getfield(modplcapcpp_ftype *type, unsigned char *count, void *dat) { return modplcap_getfield(this->msghd, (modplcap_ftype *) type, count, dat); } /* Mtodo getgrpid: Devuelve el identificador de grupo del mensaje. */ inline modplcapcpp_grpid modplcapcpp_msg::getgrpid(void) { return (modplcap_grpid) modplcap_getgrpid(this->msghd); } /* Mtodo getmsgid: Devuelve el identificador de mensaje. */ inline modplcapcpp_msgid modplcapcpp_msg::getmsgid(void) { return (modplcap_msgid) modplcap_getmsgid(this->msghd); }

726

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


#endif

D.2.2. Archivo modplcapcpp.h (plataforma Linux)


/* modplcapcpp.h: Declaracin de funciones referentes a la interfaz de la capa de aplicacin del modem PLC. */

#if !defined(__MODPLCAPCPP_H__) #define __MODPLCAPCPP_H__

/* Archivos includos necesarios. */ #ifdef __cplusplus extern "C" { #include "../modplcap/modplcap.h" } #else #include "../modplcap/modplcap.h" #endif

/* Definicin de tipos. */ /* Identificador de grupo. */ typedef unsigned char modplcapcpp_grpid; /* Identificador de mensaje. */ typedef unsigned short int modplcapcpp_msgid; /* Tipo de campo. */ typedef unsigned char modplcapcpp_ftype;

/* Definicin de constantes. */ /* Tipos de datos. */ #define MODPLCAPCPP_NULLTYPE #define MODPLCAPCPP_CHARTYPE #define MODPLCAPCPP_SINT8TYPE #define MODPLCAPCPP_UINT8TYPE #define MODPLCAPCPP_SINT16TYPE #define MODPLCAPCPP_UINT16TYPE #define MODPLCAPCPP_SINT32TYPE #define MODPLCAPCPP_UINT32TYPE #define MODPLCAPCPP_FLOATTYPE

MODPLCAP_NULLTYPE MODPLCAP_CHARTYPE MODPLCAP_SINT8TYPE MODPLCAP_UINT8TYPE MODPLCAP_SINT16TYPE MODPLCAP_UINT16TYPE MODPLCAP_SINT32TYPE MODPLCAP_UINT32TYPE MODPLCAP_FLOATTYPE

/* Declaracin de clases. */ /* Clases declaradas. */ class modplcapcpp; class modplcapcpp_msg; /* Clase modplcapcpp */ class modplcapcpp { /* Atributos y mtodos privados. */ private: modplcap_hd *handle;

/* Manejador de capa de aplicacin. */

/* Mtodos pblicos. */

FernandoArielBeunza79156

727

Tesis de Grado en Ingeniera Informtica


public: /* Constructor: Inicializa los recursos utilizados por la capa de aplicacin del modem PLC. */ modplcapcpp(int); /* Destructor: Libera los recursos utilizados por la capa de aplicacin del modem PLC. */ ~modplcapcpp(); /* Mtodo publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ int publish(modplcapcpp_grpid); /* Mtodo subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ int subscribe(modplcapcpp_grpid); /* Mtodo leave: Desvincula el dispositivo del grupo de difusin especificado. */ int leave(modplcapcpp_grpid); /* Mtodo poll: Verifica la llegada de un nuevo mensaje. */ int poll(void); /* Mtodo status: Devuelve el estado del modem PLC. */ int status(void); /* Clases amigas. */ friend class modplcapcpp_msg; }; /* Clase modplcapcpp_msg */ class modplcapcpp_msg { /* Atributos y mtodos privados. */ private: modplcap_msg *msghd;

/* Manejador de mensaje. */

/* Mtodos pblicos. */ public: /* Constructor: Crea un nuevo mensaje. */ modplcapcpp_msg(modplcapcpp *, modplcapcpp_grpid, modplcapcpp_msgid); /*

728

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Constructor: Crea un copia de un mensaje. */ modplcapcpp_msg(modplcapcpp_msg *msg); /* Constructor: Recibe un mensaje por medio de la capa de aplicacin. */ modplcapcpp_msg(modplcapcpp *hd); /* Destructor: Destruye un mensaje. */ ~modplcapcpp_msg(); /* Mtodo putfield: Agrega un nuevo campo al mensaje. */ int putfield(modplcapcpp_ftype, unsigned char, const void *); /* Mtodo sendmsg: Enva un mensaje por medio de la capa de aplicacin. */ int sendmsg(void); /* Mtodo getfield: Extrae un campo del mensaje. */ int getfield(modplcapcpp_ftype *, unsigned char *, void *); /* Mtodo getgrpid: Devuelve el identificador de grupo del mensaje. */ modplcapcpp_grpid getgrpid(void); /* Mtodo getmsgid: Devuelve el identificador de mensaje. */ modplcapcpp_msgid getmsgid(void); };

/* Implementacin de mtodos de la clase modplcapcpp. */ /* Constructor: Inicializa los recursos utilizados por la capa de aplicacin del modem PLC. */ inline modplcapcpp::modplcapcpp(int sid) { this->handle = modplcap_init(sid); } /* Destructor: Libera los recursos utilizados por la capa de aplicacin del modem PLC. */ inline modplcapcpp::~modplcapcpp() { modplcap_release(this->handle); } /*

FernandoArielBeunza79156

729

Tesis de Grado en Ingeniera Informtica


Mtodo publish: Registra el dispositivo como publicador del grupo de difusin especificado. */ inline int modplcapcpp::publish(modplcapcpp_grpid grpid) { return modplcap_publish(this->handle, (modplcap_grpid)grpid); } /* Mtodo subscribe: Registra el dispositivo como suscriptor del grupo de difusin especificado. */ inline int modplcapcpp::subscribe(modplcapcpp_grpid grpid) { return modplcap_subscribe(this->handle, (modplcap_grpid) grpid); } /* Mtodo leave: Desvincula el dispositivo del grupo de difusin especificado. */ inline int modplcapcpp::leave(modplcapcpp_grpid grpid) { return modplcap_leave(this->handle, (modplcap_grpid) grpid); } /* Mtodo poll: Verifica la llegada de un nuevo mensaje. */ inline int modplcapcpp::poll(void) { return modplcap_poll(this->handle); } /* Mtodo status: Devuelve el estado del modem PLC. */ inline int modplcapcpp::status(void) { return modplcap_status(this->handle); }

/* Implementacin de mtodos de la clase modplcapcpp_msg. */ /* Constructor: Crea un nuevo mensaje. */ inline modplcapcpp_msg::modplcapcpp_msg(modplcapcpp *hd, modplcapcpp_grpid grpid, modplcapcpp_msgid msgid) { this->msghd = new modplcap_msg; if (!this->msghd) return; modplcap_newmsg(hd->handle, (modplcap_msg *) (this->msghd), (modplcap_grpid) grpid, (modplcap_msgid) msgid); } /* Constructor: Crea un copia de un mensaje. */ inline modplcapcpp_msg::modplcapcpp_msg(modplcapcpp_msg *msg) { this->msghd = new modplcap_msg; if (!this->msghd) return;

730

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


if (!modplcap_copymsg(this->msghd, msg->msghd)) delete this->msghd; } /* Constructor: Recibe un mensaje por medio de la capa de aplicacin. */ inline modplcapcpp_msg::modplcapcpp_msg(modplcapcpp *hd) { this->msghd = new modplcap_msg; if (!this->msghd) return; if (!modplcap_receivemsg(hd->handle, this->msghd)) delete this->msghd; } /* Destructor: Destruye un mensaje. */ inline modplcapcpp_msg::~modplcapcpp_msg() { if (!this->msghd) return; modplcap_destroymsg(this->msghd); delete this->msghd; } /* Mtodo putfield: Agrega un nuevo campo al mensaje. */ inline int modplcapcpp_msg::putfield(modplcapcpp_ftype type, unsigned char count, const void *dat) { return modplcap_putfield(this->msghd, (modplcap_ftype) type, count, dat); } /* Mtodo sendmsg: Enva un mensaje por medio de la capa de aplicacin. */ inline int modplcapcpp_msg::sendmsg(void) { return modplcap_sendmsg(this->msghd); } /* Mtodo getfield: Extrae un campo del mensaje. */ inline int modplcapcpp_msg::getfield(modplcapcpp_ftype *type, unsigned char *count, void *dat) { return modplcap_getfield(this->msghd, (modplcap_ftype *) type, count, dat); } /* Mtodo getgrpid: Devuelve el identificador de grupo del mensaje. */ inline modplcapcpp_grpid modplcapcpp_msg::getgrpid(void) { return (modplcap_grpid) modplcap_getgrpid(this->msghd); } /* Mtodo getmsgid: Devuelve el identificador de mensaje. */

FernandoArielBeunza79156

731

Tesis de Grado en Ingeniera Informtica


inline modplcapcpp_msgid modplcapcpp_msg::getmsgid(void) { return (modplcap_msgid) modplcap_getmsgid(this->msghd); }

#endif

732

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Apndice E: Interfaz Simulink


En el ste apndice se describe y detalla la interfaz Simulink conformada por una biblioteca de bloques. Tambin se detalla el cdigo fuente asociado a la implementacin de la mencionada biblioteca de bloques.

E.1. Descripcin
La interfaz para el entorno Simulink es una extensin de la capa de aplicacin que permite un uso ms interactivo de las comunicaciones a travs de la red PLC. La capa de aplicacin provee una interfaz apropiada para entornos de programacin en donde se implementan algoritmos que hacen uso de la red PLC, lo que resulta cmodo para usuarios con conocimientos de programacin. Para usuario sin ste tipo de conocimiento resulta ms adecuado la utilizacin de un entorno grfico que permita representar algoritmos en forma de modelos grficos. Simulink es una herramienta incluida dentro de MATLAB que permite la modelizacin grfica de sistemas de control mediante la interconexin de bloques funcionales. La interfaz Simulink diseada en el presente trabajo provee una biblioteca de bloques Simulink que permiten agregar las funcionalidades de comunicacin por medio de redes PLC a cualquier modelo de control realizado en Simulink.

E.2. Biblioteca de bloques Simulink


La biblioteca de bloques funcionales es un conjunto de bloques que proveen bsicamente las funciones de conexin al modem PLC, envo y recepcin de mensajes. Los bloques que proveen dichas funciones bsicas, independientemente de la funcionalidad que cumplen, cuentan con dos salidas: una asociada al manejador de la conexin y otra un indicador de resultado de la operacin llevada a cabo por el bloque. Salvo uno de los bloques encargado de la conexin al modem PLC, el resto cuenta tambin con dos entradas tambin asociadas al manejador de la conexin y al resultado de la operacin realizada por el bloque predecesor. El motivo de sto se debe a que cualquier operacin de comunicacin necesita del manejador de conexin y tambin es necesario conocer como se llev a cabo la operacin de modo tal que se puedan encadenar cada una de las operaciones como si se tratara de la ejecucin de un algoritmo y en caso de que alguna falle se pueda implementar una alternativa de ejecucin. Adems de las funciones bsicas anteriores existen otras adicionales utilizadas para el armado y desarmado de mensajes, que permiten la especificacin del grupo de difusin por el cual se enva o recibe el mensaje, el identificador de mensaje y los campos de datos que componen al mensaje. A continuacin se muestra el contenido de la biblioteca de bloques correspondientes al manejo del modem PLC.

FernandoArielBeunza79156

733

Tesis de Grado en Ingeniera Informtica

Figura E1. Biblioteca de bloques funcionales.

Algunos de los bloques funcionales mostrados en la figura E1 presentan una serie de parmetros configurables como el caso de los bloques Modem PLC Interface, Modem PLC Create Message, Modem PLC Receive Message, Modem PLC Put Field y Modem PLC Get Field. El primer bloque al cual se hace referencia es el relacionado a la conexin con el modem PLC denominado Modem PLC Interface. Dicho bloque se encarga de establecer las comunicaciones con el mencionado modem y presenta como nico parmetro configurable el nmero de puerto serie (correspondiendo 1 a COM1, 2 a COM2, etc.) al cual se encuentra conectado el modem PLC como se puede observar en la figura E2.

Figura E2. Parmetros configurables correspondientes al bloque Modem PLC Interface.

El segundo bloque al cual se hace referencia se denomina Modem PLC Create Message, utilizado para crear un nuevo mensaje. Con este bloque funcional se inicializa un mensaje en donde se especifica el identificador de grupo de difusin que se utiliza para el envo del mensaje, y un 734 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica identificador de mensaje utilizado para que el destinatario del mensaje pueda identificar y procesar el mensaje recibido. En la figura E3 se pueden observar los parmetros configurables a los cuales se hacia referencia anteriormente.

Figura E3. Parmetros configurables correspondientes al bloque Modem PLC Create Message.

El bloque denominado Modem PLC Put Field, es utilizado para agregar un campo de datos a un mensaje previamente creado con el bloque descripto anteriormente. El nico parmetro configurable que presenta hace referencia al tipo de datos que contiene el campo como se puede observar en la figura E4. La multiplicidad de los datos de campo est dada por la entrada de datos del bloque, si la entrada se compone de una seal, la multiplicidad del campo sera uno; y si se tratan de varias seales concentradas por ejemplo por el bloque Multiplexor provisto por Simulink, la multiplicidad del campo la determinar la cantidad de seales que ingresan al multiplexor.

Figura E4. Parmetros configurables correspondientes al bloque Modem PLC Put Field.

El bloque denominado Modem PLC Send Message, es utilizado para enviar un mensaje armado por medio de los dos bloques anteriormente descriptos. No presenta ningn parmetro configurable ya que todo lo referente al mensaje se especifica por medio de los dos bloques anteriores. El bloque denominado Modem PLC Receive Message, es utilizado recibir un mensaje por medio del grupo de difusin especificado como parmetro, y asociado a un determinado identificador de mensaje opcionalmente tambin especificado como parmetro, como se muestra en la figura E5. El identificador de grupo es obligatorio especificarlo, mientras que el identificador de mensaje, con slo especificar el valor -1 se indica que se acepta cualquier mensaje independientemente del identificador de mensaje que posean.

FernandoArielBeunza79156

735

Tesis de Grado en Ingeniera Informtica

Figura E5. Parmetros configurables correspondientes al bloque Modem PLC Receive Message.

El bloque denominado Modem PLC Get Field, es utilizado para extraer un campo de datos de un mensaje recibido. Como parmetro configurable (figura E6) posee la cantidad de datos del campo que se desea recibir que no es necesario que conocida con la cantidad de datos recibidos. Si la cantidad especificada es mayor a la recibida, el bloque devuelve en su salida la cantidad de datos recibida; y si es menor, devuelve la cantidad especificada.

Figura E6. Parmetros configurables correspondientes al bloque Modem PLC Get Field.

El bloque denominado Modem PLC Real Time, brinda la posibilidad aproximar el tiempo de simulacin al tiempo real transcurrido, para poder simular modelos en un tiempo similar al real. Este bloque no presenta parmetros configurables pero posee una salida que devuelve el tiempo real que se debe agregar en cada paso de simulacin para aproximar el tiempo de simulacin al tiempo real. Cuando devuelve un valor negativo, indica que el tiempo real transcurrido supera al tiempo de simulacin.

E.3. Cdigo fuente


La interfaz Simulink se compone de seis bloques que permiten utilizar de forma interactiva las funcionalidades que ofrece la capa de aplicacin. Cada bloque lleva asociado un cdigo fuente en lenguaje C que se compila generando una biblioteca dinmica. Dichas bibliotecas dinmicas interactan con la capa de aplicacin por medio de otra biblioteca dinmica encargada de compatibilizar la interfaz Simulink con la interfaz de la capa anteriormente mencionada. 736 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Bloques Simulink

modem_plc_interface.dllmodem_plc_create_message.dllmodem_plc_put_field.dll modem_plc_send_message.dllmodem_plc_receive_message.dll modem_plc_get_field.dll modplc_simulink.dll

Capa de aplicacin

modplcap.dll

Figura E7. Diagrama de organizacin de cdigo.

En la figura E7 se puede observar la organizacin de los elementos descriptos dentro del esquema de capas propuesto en el presente trabajo.

E.3.1. Archivo modplc_simulink.c


/* modplc_simulink.c: Implementacin de funciones referentes a la interfaz Simulink del modem PLC. */

/* Archivos includos necesarios. */ #include <stdio.h> #include <math.h> #include "..\modplcap\modplcap.h"

/* Definicin de tipos. */ /* Estructura de nodo de lista de mensajes recibidos. */ typedef struct { modplcap_msg *msg; void *next; } listmsg_node;

/* Mensaje. */ /* Puntero al prximo nodo. */

/* Estructura de manejador de comunicacin entre bloques Simulink del Modem PLC. */ typedef struct { modplcap_hd *hd; /* Manejador de capa de aplicacin del Modem PLC. */ modplcap_msg *msg; /* Mensaje a enviar o recibido. */ int groups[256]; /* Grupos suscriptos. */ listmsg_node *frecvmsg; /* Puntero al nodo del primer mensaje recibido. */ listmsg_node *lrecvmsg; /* Puntero al nodo del ltimo mensaje recibido. */ } modplcsimulink_hd;

/* Definicin de constantes. */ /* Tipos de datos. */ #define MODPLCSIMULINK_CHARTYPE #define MODPLCSIMULINK_SINT8TYPE #define MODPLCSIMULINK_UINT8TYPE #define MODPLCSIMULINK_SINT16TYPE #define MODPLCSIMULINK_UINT16TYPE #define MODPLCSIMULINK_SINT32TYPE

1 2 3 4 5 6

FernandoArielBeunza79156

737

Tesis de Grado en Ingeniera Informtica


#define MODPLCSIMULINK_UINT32TYPE #define MODPLCSIMULINK_FLOATTYPE 7 8

/* Implementacin de funciones pblicas referentes al bloque Modem PLC Interface. */ /* Funcin ModemPlcInterface_Initialize: Inicializa el bloque Modem PLC Interface. */ void *ModemPlcInterface_Initialize(int port) { /* Variables. */ short int i; modplcsimulink_hd *handle;

/* Contador. */ /* Manejador de comunicacin entre bloques Simulink del Modem PLC. */

/* Inicializa el bloque. */ handle = NULL; while(1) { /* Carga la biblioteca. */ if (!modplcap_loadlib()) break; /* Inicializa el manejador de comunicacin entre bloques Simulink del Modem PLC. */ handle = (modplcsimulink_hd *) malloc(sizeof(modplcsimulink_hd)); if (!handle) break; /* Inicializa el manejador de capa fsica del modem PLC.. */ handle->hd = modplcap_init(port); if (!handle->hd) break; /* Inicializa el puntero al mensaje a enviar o recibido. */ handle->msg = NULL; /* Inicializa la tabla de suscripciones a grupos. */ for(i = 0; i < 255; i++) handle->groups[i] = 0; /* Inicializa la lista de mensajes recibidos. */ handle->frecvmsg = NULL; handle->lrecvmsg = NULL; /* xito. */ return handle; } if (handle) { modplcap_release(handle->hd); free(handle); handle = NULL; } return handle; } /* Funcin ModemPlcInterface_Output: Ejecuta el bloque Modem PLC Interface. */ int ModemPlcInterface_Output(void *handle) { /* Variables. */ listmsg_node *node;

/* Nodo de lista de mensajes. */

/* Verifica que manejador de comunicacin entre bloques Simulink del Modem PLC exista. */ if (!handle) return 0;

738

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Verifica el estado del Model PLC. */ if (!modplcap_status(((modplcsimulink_hd *) handle)->hd)) return 0; /* Recibe mensajes disponibles. */ while(modplcap_poll(((modplcsimulink_hd *) handle)->hd)) { /* Crea un nuevo nodo. */ node = (listmsg_node *) malloc(sizeof(listmsg_node)); if (!node) break; /* Recibe el mensaje. */ node->msg = (modplcap_msg *) malloc(sizeof(modplcap_msg)); if (!node->msg) { free(node); break; } if (!modplcap_receivemsg(((modplcsimulink_hd *) handle)->hd, node->msg)) { free(node->msg); free(node); break; } node->next = NULL; /* Agrega el nuevo nodo a la lista. */ if (!((modplcsimulink_hd *) handle)->frecvmsg) { ((modplcsimulink_hd *) handle)->frecvmsg = node; ((modplcsimulink_hd *) handle)->lrecvmsg = node; } else { ((modplcsimulink_hd *) handle)->lrecvmsg->next = node; ((modplcsimulink_hd *) handle)->lrecvmsg = node; } break; } return 1; } /* Funcin ModemPlcInterface_Terminate: Libera los recursos utilizados por el bloque Modem PLC Interface. */ int ModemPlcInterface_Terminate(void *handle) { /* Variables. */ listmsg_node *node; listmsg_node *next;

/* Nodo de lista de mensajes. */ /* Prximo nodo en la lista de mensajes. */

/* Verifica que manejador de comunicacin entre bloques Simulink del Modem PLC exista. */ if (!handle) return 0; /* Limpia la lista de mensajes recibidos. */ node = ((modplcsimulink_hd *) handle)->frecvmsg; while(node) { /* Destruye el mensaje almacenado. */ modplcap_destroymsg(node->msg); /* Almacena el puntero al siguiente nodo. */ next = (listmsg_node *) node->next; /* Destruye el nodo. */ free(node);

FernandoArielBeunza79156

739

Tesis de Grado en Ingeniera Informtica


/* Carga el siguiente nodo. */ node = next; } /* Libera los recursos utilizados por la capa de aplicacin del modem PLC. */ modplcap_release(((modplcsimulink_hd *) handle)->hd); /* Libera el manejador de comunicacin entre bloques Simulink del Modem PLC. */ free(handle); /* xito. */ return 1; }

/* Implementacin de funciones pblicas referentes al bloque Modem PLC Create Message. */ /* Funcin ModemPlcCreateMessage_Initialize: Inicializa el bloque Modem PLC Create Message. */ void *ModemPlcCreateMessage_Initialize(void) { return malloc(sizeof(modplcap_msg)); } /* Funcin ModemPlcCreateMessage_Output: Ejecuta el bloque Modem PLC Create Message. */ int ModemPlcCreateMessage_Output(void *handle, void *msg, int grpid, int msgid) { /* Verifica que manejador de comunicacin entre bloques Simulink del Modem PLC exista. */ if (!handle) return 0; /* Verifica que exista el mensaje. */ if (!msg) return 0; /* Destruye el mensaje anterior, */ if (((modplcsimulink_hd *) handle)->msg) { modplcap_destroymsg(msg); ((modplcsimulink_hd *) handle)->msg = NULL; } /* Ejecuta un ciclo Simulink. */ while(1) { /* Verifica que manejador de comunicacin entre bloques Simulink del Modem PLC y el manejador de mensaje exista. */ if (!handle) break; /* Establace al modem PLC como publicador del grupo asociado al mensaje que se quiere crear. */ if (!((modplcsimulink_hd *) handle)->groups[(modplcap_grpid) grpid]) { modplcap_publish(((modplcsimulink_hd *) handle)->hd, (modplcap_grpid) grpid); ((modplcsimulink_hd *) handle)->groups[(modplcap_grpid) grpid] = 1; } /* Crea un nuevo mensaje. */ if (!modplcap_newmsg(((modplcsimulink_hd *) handle)->hd, (modplcap_msg *) msg, (modplcap_grpid) grpid, (modplcap_msgid) msgid)) break;

740

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Carga el nuevo mensaje en el manejador. */ ((modplcsimulink_hd *) handle)->msg = (modplcap_msg *) msg; /* Devuelve el manejador de comunicacin entre bloques Simulink del Modem PLC. */ return 1; } /* No se pudo inicializar el mensaje. */ return 0; } /* Funcin ModemPlcCreateMessage_Terminate: Libera los recursos utilizados por el bloque Modem PLC Create Message. */ int ModemPlcCreateMessage_Terminate(void *msg) { /* Destruye el mensaje anterior. */ if (!msg) return 0; modplcap_destroymsg((modplcap_msg *) msg); free(msg); return 1; }

/* Implementacin de funciones pblicas referentes al bloque Modem PLC Put Field. */ /* Funcin ModemPlcPutField_Initialize: Inicializa el bloque Modem PLC Put Field. */ void *ModemPlcPutField_Initialize(void) { return NULL; } /* Funcin ModemPlcPutField_Output: Ejecuta el bloque Modem PLC Put Field. */ int ModemPlcPutField_Output(void *handle, int type, int count, double *dat) { /* Variables. */ int i; /* Contador. */ int result; /* Resultado de la operacin de agregado del campo de datos. */ char *datchar; /* Puntero a datos tipo caracter. */ char *datsint8; /* Puntero a datos tipo entero con signo de 8 bits. */ unsigned char *datuint8; /* Puntero a datos tipo entero sin signo de 8 bits. */ short int *datsint16; /* Puntero a datos tipo entero con signo de 16 bits. */ unsigned short int *datuint16; /* Puntero a datos tipo entero sin signo de 16 bits. */ long int *datsint32; /* Puntero a datos tipo entero con signo de 32 bits. */ unsigned long int *datuint32; /* Puntero a datos tipo entero sin signo de 32 bits. */ float *datfloat; /* Puntero a datos tipo punto flotante. */

/* Verifica que manejador de comunicacin entre bloques Simulink del Modem PLC exista. */ if (!handle) return 0; /* Ejecuta un ciclo Simulink. */

FernandoArielBeunza79156

741

Tesis de Grado en Ingeniera Informtica


while(1) { /* Verifica que manejador de comunicacin entre bloques Simulink del Modem PLC exista. */ if (!handle) break; if (!((modplcsimulink_hd *) handle)->msg) break; /* Carga el campo de datos. */ result = 0; if (count > 255) count = 255; switch(type) { /* Tipo caracter. */ case MODPLCSIMULINK_CHARTYPE: datchar = (char *) malloc(count * sizeof(char)); if (!datchar) break; for(i = 0; i < count; i++) datchar[i] = (char) ceil(dat[i]); result = modplcap_putfield(((modplcsimulink_hd *) handle)->msg, MODPLCAP_CHARTYPE, (unsigned char) count, datchar); free(datchar); break; /* Tipo entero con signo de 8 bits. */ case MODPLCSIMULINK_SINT8TYPE: datsint8 = (char *) malloc(count * sizeof(char)); if (!datsint8) break; for(i = 0; i < count; i++) datsint8[i] = (char) ceil(dat[i]); result = modplcap_putfield(((modplcsimulink_hd *) handle)->msg, MODPLCAP_SINT8TYPE, (unsigned char) count, datsint8); free(datsint8); break; /* Tipo entero sin signo de 8 bits. */ case MODPLCSIMULINK_UINT8TYPE: datuint8 = (unsigned char *) malloc(count * sizeof(unsigned char)); if (!datuint8) break; for(i = 0; i < count; i++) datuint8[i] = (unsigned char) ceil(dat[i]); result = modplcap_putfield(((modplcsimulink_hd *) handle)->msg, MODPLCAP_UINT8TYPE, (unsigned char) count, datuint8); free(datuint8); break; /* Tipo entero con signo de 16 bits. */ case MODPLCSIMULINK_SINT16TYPE: datsint16 = (short int *) malloc(count * sizeof(short int)); if (!datsint16) break; for(i = 0; i < count; i++) datsint16[i] = (short int) ceil(dat[i]); result = modplcap_putfield(((modplcsimulink_hd *) handle)->msg, MODPLCAP_SINT16TYPE, (unsigned char) count, datsint16); free(datsint16); break; /* Tipo entero sin signo de 16 bits. */ case MODPLCSIMULINK_UINT16TYPE: datuint16 = (unsigned short int *) malloc(count * sizeof(unsigned short int)); if (!datuint16) break; for(i = 0; i < count; i++) datuint16[i] = (unsigned short int) ceil(dat[i]); result = modplcap_putfield(((modplcsimulink_hd *) handle)->msg, MODPLCAP_UINT16TYPE, (unsigned char) count, datuint16); free(datuint16); break;

742

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Tipo entero con signo de 32 bits. */ case MODPLCSIMULINK_SINT32TYPE: datsint32 = (long int *) malloc(count * sizeof(long int)); if (!datsint32) break; for(i = 0; i < count; i++) datsint32[i] = (long int) ceil(dat[i]); result = modplcap_putfield(((modplcsimulink_hd *) handle)->msg, MODPLCAP_SINT32TYPE, (unsigned char) count, datsint32); free(datsint32); break; /* Tipo entero sin signo de 32 bits. */ case MODPLCSIMULINK_UINT32TYPE: datuint32 = (unsigned long int *) malloc(count * sizeof(unsigned long int)); if (!datuint32) break; for(i = 0; i < count; i++) datuint32[i] = (unsigned long int) ceil(dat[i]); result = modplcap_putfield(((modplcsimulink_hd *) handle)->msg, MODPLCAP_UINT32TYPE, (unsigned char) count, datuint32); free(datuint32); break; /* Tipo punto flotante. */ case MODPLCSIMULINK_FLOATTYPE: datfloat = (float *) malloc(count * sizeof(float)); if (!datfloat) break; for(i = 0; i < count; i++) datfloat[i] = (float) ceil(dat[i]); result = modplcap_putfield(((modplcsimulink_hd *) handle)->msg, MODPLCAP_FLOATTYPE, (unsigned char) count, datfloat); free(datfloat); break; /* Tipo desconocido. */ default: break; } if (!result) break; /* Devuelve el manejador de comunicacin entre bloques Simulink del Modem PLC. */ return 1; } /* No se pudo agregar el campo de datos al mensaje. */ return 0; } /* Funcin ModemPlcPutField_Terminate: Libera los recursos utilizados por el bloque Modem PLC Put Field. */ int ModemPlcPutField_Terminate(void) { return 1; }

/* Implementacin de funciones pblicas referentes al bloque Modem PLC Send Message. */ /* Funcin ModemPlcSendMessage_Initialize: Inicializa el bloque Modem PLC Send Message. */ void *ModemPlcSendMessage_Initialize(void) {

FernandoArielBeunza79156

743

Tesis de Grado en Ingeniera Informtica


return NULL; } /* Funcin ModemPlcSendMessage_Output: Ejecuta el bloque Modem PLC Send Message. */ int ModemPlcSendMessage_Output(void *handle) { /* Verifica que manejador de comunicacin entre bloques Simulink del Modem PLC exista. */ if (!handle) return 0; /* Ejecuta un ciclo Simulink. */ while(1) { /* Verifica que manejador de comunicacin entre bloques Simulink del Modem PLC exista. */ if (!handle) break; /* Enva el mensaje. */ modplcap_sendmsg(((modplcsimulink_hd *) handle)->msg); /* Devuelve el manejador de comunicacin entre bloques Simulink del Modem PLC. */ return 1; } /* No se pudo enviar el mensaje. */ return 0; } /* Funcin ModemPlcSendMessage_Terminate: Libera los recursos utilizados por el bloque Modem PLC Send Message. */ int ModemPlcSendMessage_Terminate(void) { return 1; }

/* Implementacin de funciones pblicas referentes al bloque Modem PLC Receive Message. */ /* Funcin ModemPlcReceiveMessage_Initialize: Inicializa el bloque Modem PLC Receive Message. */ void *ModemPlcReceiveMessage_Initialize(void) { return malloc(sizeof(modplcap_msg)); } /* Funcin ModemPlcReceiveMessage_Output: Ejecuta el bloque Modem PLC Receive Message. */ int ModemPlcReceiveMessage_Output(void *handle, void *msg, int grpid, int msgid) { /* Variables. */ listmsg_node *currnode; /* Nodo corriente de lista de mensajes. */ listmsg_node *prevnode; /* Nodo previo al corriente de lista de mensajes. */

/* Verifica que manejador de comunicacin entre bloques Simulink del Modem PLC exista. */ if (!handle) return 0;

744

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Veririca que exista el mensaje. */ if (!msg) return 0; /* Destruye el mensaje anterior, */ if (((modplcsimulink_hd *) handle)->msg) { modplcap_destroymsg(msg); ((modplcsimulink_hd *) handle)->msg = NULL; } /* Ejecuta un ciclo Simulink. */ while(1) { /* Verifica que manejador de comunicacin entre bloques Simulink del Modem PLC y el manejador de mensaje exista. */ if (!handle) break; /* Establace al modem PLC como suscriptor del grupo asociado al mensaje recibido. */ if (!((modplcsimulink_hd *) handle)->groups[(modplcap_grpid) grpid]) { modplcap_subscribe(((modplcsimulink_hd *) handle)->hd, (modplcap_grpid) grpid); ((modplcsimulink_hd *) handle)->groups[(modplcap_grpid) grpid] = 1; } /* Busca el siguiente mensaje en la lista. */ prevnode = NULL; currnode = ((modplcsimulink_hd *) handle)->frecvmsg; while(currnode) { /* Filtra el mensaje por identificador de grupo. */ if (modplcap_getgrpid(currnode->msg) != grpid) { prevnode = currnode; currnode = currnode->next; continue; } /* Filtra el mensaje por identificador de mensaje. */ if (msgid > -1) { if (modplcap_getmsgid(currnode->msg) != msgid) { prevnode = currnode; currnode = currnode->next; continue; } } /* Obtiene el mensaje encontrado. */ msg = currnode->msg; /* Elimina el mensaje de la lista. */ if (prevnode) prevnode->next = currnode->next; else ((modplcsimulink_hd *) handle)->frecvmsg = currnode->next; if (((modplcsimulink_hd *) handle)->lrecvmsg == currnode) ((modplcsimulink_hd *) handle)->lrecvmsg = prevnode; free(currnode); break; } /* Carga el mensaje recibido en el manejador. */ if (currnode) ((modplcsimulink_hd *) handle)->msg = (modplcap_msg *) msg; else { ((modplcsimulink_hd *) handle)->msg = NULL;

FernandoArielBeunza79156

745

Tesis de Grado en Ingeniera Informtica


break; } /* Devuelve el manejador de comunicacin entre bloques Simulink del Modem PLC. */ return 1; } /* No se pudo recibir el mensaje. */ return 0; } /* Funcin ModemPlcReceiveMessage_Terminate: Libera los recursos utilizados por el bloque Modem PLC Receive Message. */ int ModemPlcReceiveMessage_Terminate(void *msg) { /* Destruye el mensaje anterior. */ if (!msg) return 0; modplcap_destroymsg((modplcap_msg *) msg); free(msg); return 1; }

/* Implementacin de funciones pblicas referentes al bloque Modem PLC Get Field. */ /* Funcin ModemPlcGetField_Initialize: Inicializa el bloque Modem PLC Get Field. */ void *ModemPlcGetField_Initialize(void) { return NULL; } /* Funcin ModemPlcGetField_Output: Ejecuta el bloque Modem PLC Get Field. */ int ModemPlcGetField_Output(void *handle, unsigned char count, double *dat) { /* Variables. */ int i; /* Contador. */ int result; /* Resultado de la operacin de agregado del campo de datos. */ modplcap_ftype rtype; /* Identificador de tipo de dato. */ unsigned char rcount; /* Cantidad de datos recibidos. */ void *rdat; /* Puntero a los datos recibidos. */ char *datchar; /* Puntero a datos tipo caracter. */ char *datsint8; /* Puntero a datos tipo entero con signo de 8 bits. */ unsigned char *datuint8; /* Puntero a datos tipo entero sin signo de 8 bits. */ short int *datsint16; /* Puntero a datos tipo entero con signo de 16 bits. */ unsigned short int *datuint16; /* Puntero a datos tipo entero sin signo de 16 bits. */ long int *datsint32; /* Puntero a datos tipo entero con signo de 32 bits. */ unsigned long int *datuint32; /* Puntero a datos tipo entero sin signo de 32 bits. */ float *datfloat; /* Puntero a datos tipo punto flotante. */

/* Verifica que manejador de comunicacin entre bloques Simulink del Modem

746

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


PLC exista. */ if (!handle) return 0; /* Ejecuta un ciclo Simulink. */ while(1) { /* Verifica que manejador de comunicacin entre bloques Simulink del Modem PLC exista. */ if (!handle) break; if (!((modplcsimulink_hd *) handle)->msg) break; /* Carga el campo de datos. */ rdat = malloc(256 * sizeof(unsigned long int)); if (!rdat) break; if (!modplcap_getfield(((modplcsimulink_hd *) handle)->msg, &rtype, &rcount, rdat)) break; result = 1; datchar = (char *) rdat; datsint8 = (char *) rdat; datuint8 = (unsigned char *) rdat; datsint16 = (short int *) rdat; datuint16 = (unsigned short int *) rdat; datsint32 = (long int *) rdat; datuint32 = (unsigned long int *) rdat; datfloat = (float *) rdat; switch(rtype) { /* Tipo caracter. */ case MODPLCSIMULINK_CHARTYPE: for(i = 0; i < count; i++) { if (i < rcount) dat[i] = (double) datchar[i]; else dat[i] = 0; } break; /* Tipo entero con signo de 8 bits. */ case MODPLCSIMULINK_SINT8TYPE: for(i = 0; i < count; i++) { if (i < rcount) dat[i] = (double) datsint8[i]; else dat[i] = 0; } break; /* Tipo entero sin signo de 8 bits. */ case MODPLCSIMULINK_UINT8TYPE: for(i = 0; i < count; i++) { if (i < rcount) dat[i] = (double) datuint8[i]; else dat[i] = 0; } break; /* Tipo entero con signo de 16 bits. */ case MODPLCSIMULINK_SINT16TYPE: for(i = 0; i < count; i++) { if (i < rcount) dat[i] = (double) datsint16[i]; else dat[i] = 0; } break;

FernandoArielBeunza79156

747

Tesis de Grado en Ingeniera Informtica


/* Tipo entero sin signo de 16 bits. */ case MODPLCSIMULINK_UINT16TYPE: for(i = 0; i < count; i++) { if (i < rcount) dat[i] = (double) datuint16[i]; else dat[i] = 0; } break; /* Tipo entero con signo de 32 bits. */ case MODPLCSIMULINK_SINT32TYPE: for(i = 0; i < count; i++) { if (i < rcount) dat[i] = (double) datsint32[i]; else dat[i] = 0; } break; /* Tipo entero sin signo de 32 bits. */ case MODPLCSIMULINK_UINT32TYPE: for(i = 0; i < count; i++) { if (i < rcount) dat[i] = (double) datuint32[i]; else dat[i] = 0; } break; /* Tipo punto flotante. */ case MODPLCSIMULINK_FLOATTYPE: for(i = 0; i < count; i++) { if (i < rcount) dat[i] = (double) datfloat[i]; else dat[i] = 0; } break; /* Tipo desconocido. */ default: result = 0; break; } free(rdat); if (!result) break; /* Devuelve el manejador de comunicacin entre bloques Simulink del Modem PLC. */ return 1; } /* No se pudo agregar el campo de datos al mensaje. */ return 0; } /* Funcin ModemPlcGetField_Terminate: Libera los recursos utilizados por el bloque Modem PLC Get Field. */ int ModemPlcGetField_Terminate(void) { return 1; }

748

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

E.3.2. Archivo MODEM_PLC_INTERFACE.C


/* MODEM_PLC_INTERFACE.C: Se encarga de configurar la interfaz donde se encuentran conectado el modem PLC. */ /* Especifica el nombre de la S-Function. */ #define S_FUNCTION_NAME #define S_FUNCTION_LEVEL

Modem_PLC_Interface 2

/* Archivos includos necesarios. */ #include <windows.h> #include <math.h> #include "simstruc.h" #include "tmwtypes.h" #if defined(MATLAB_MEX_FILE) #include "mex.h" #endif

/* Variables globales. */ static void *handle;

/* Manejador de comunicacin entre bloques Simulink del Modem PLC. */

/* Declaracin de funciones externas. */ void * (*ModemPlcInterface_Initialize)(int); int (*ModemPlcInterface_Output)(void *); int (*ModemPlcInterface_Terminate)(void *);

/* Implementacin de funciones. */ /* Funcin mdlInitializeSizes: Establece las dimensiones de las entradas y salidas del bloque Simulink y la cantidad de parmetros que requiere. */ static void mdlInitializeSizes(SimStruct *S) { /* Inicializa dimensiones de entradas y salidas. */ DECL_AND_INIT_DIMSINFO(inputDimsInfo); DECL_AND_INIT_DIMSINFO(outputDimsInfo); /* Define la cantidad de parmetros que requiere el bloque Simulink. */ ssSetNumSFcnParams(S, 1); if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) return; /* Define la cantidad de entradas que requiere el bloque Simulink. */ if (!ssSetNumInputPorts(S, 0)) return; /* Define la cantidad de salidas que requiere el bloque Simulink. */ if (!ssSetNumOutputPorts(S, 2)) return; ssSetOutputPortWidth(S, 0, 1); ssSetOutputPortWidth(S, 1, 1); ssSetNumSampleTimes(S, 1); ssSetNumRWork(S, DYNAMICALLY_SIZED); ssSetNumIWork(S, DYNAMICALLY_SIZED); ssSetNumPWork(S, DYNAMICALLY_SIZED); ssSetNumModes(S, DYNAMICALLY_SIZED); /* */ ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE); }

FernandoArielBeunza79156

749

Tesis de Grado en Ingeniera Informtica


/* Funcin mdlInitializeSampleTimes: Establece el tiempo de muestreo utilizado durante la simulacin. */ static void mdlInitializeSampleTimes(SimStruct *S) { /* Variables. */ struct HINSTANCE__ *hlib;

/* Manejador de biblioteca dinmica. */

/* Establece el tiempo de muestreo. */ ssSetSampleTime(S, 0, 0.0); ssSetOffsetTime(S, 0, 0.0); /* Carga la biblioteca. */ hlib = NULL; ModemPlcInterface_Initialize = NULL; ModemPlcInterface_Output = NULL; ModemPlcInterface_Terminate = NULL; hlib = LoadLibrary("MODPLC_SIMULINK"); if (!hlib) return; ModemPlcInterface_Initialize = (void * (*)(int)) GetProcAddress(hlib, "ModemPlcInterface_Initialize"); ModemPlcInterface_Output = (int (*)(void *)) GetProcAddress(hlib, "ModemPlcInterface_Output"); ModemPlcInterface_Terminate = (int (*)(void *)) GetProcAddress(hlib, "ModemPlcInterface_Terminate"); if ((!ModemPlcInterface_Initialize) || (!ModemPlcInterface_Output) || (!ModemPlcInterface_Terminate)) return; /* Inicializa el bloque Simulink. */ handle = ModemPlcInterface_Initialize( (int) ceil(*mxGetPr(ssGetSFcnParam(S, 0)))); } /* Funcin mdlOutputs: Devuelve el resultado de la ejecucin de un ciclo de simulacin del bloque Simulink. */ static void mdlOutputs(SimStruct *S, int_T tid) { /* Variables. */ int *flag_out;

unsigned long int *handle_out;

/* Puntero al indicador de resultado de ejecucin de la presente operacin. */ /* Puntero al manejador de conexin de salida. */

/* Carga salidas del bloque Simulink. */ handle_out = (unsigned long int *) ssGetOutputPortSignal(S, 0); flag_out = (int *) ssGetOutputPortSignal(S, 1); /* Ejecuta un ciclo de simulacin para el bloque Simulink. */ while(1) { /* Verifica que manejador de comunicacin entre bloques Simulink del Modem PLC exista. */ if (!handle) break; /* Ejecuta un ciclo Simulink. */ if (!ModemPlcInterface_Output(handle)) break; /* Devuelve el manejador de comunicacin entre bloques Simulink del Modem PLC. */ *handle_out = (unsigned long int) handle; *flag_out = 1; return;

750

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


} /* No se pudo ejecutar el ciclo de simulacin. */ *handle_out = 0; *flag_out = 0; } /* Funcin mdlTerminate: Finaliza la ejecucin de la simulacin del bloque Simulink. */ static void mdlTerminate(SimStruct *S) { ModemPlcInterface_Terminate(handle); }

/* Definido por Simulink. */ #ifdef MATLAB_MEX_FILE #include "simulink.c" #else #include "cg_sfun.h" #endif

E.3.3. Archivo MODEM_PLC_CREATE_MESSAGE.C


/* MODEM_PLC_CREATE_MESSAGE.C: Se encarga de inicializar un nuevo mensaje. */ /* Especifica el nombre de la S-Function. */ #define S_FUNCTION_NAME #define S_FUNCTION_LEVEL

Modem_PLC_Create_Message 2

/* Archivos includos necesarios. */ #include <windows.h> #include <math.h> #include "simstruc.h" #include "tmwtypes.h" #if defined(MATLAB_MEX_FILE) #include "mex.h" #endif

/* Variables globales. */ static int grpid; static int msgid; static void *msg;

/* Identificador de grupo. */ /* Identificador de mensaje. */ /* Puntero al mensaje. */

/* Declaracin de funciones externas. */ void * (*ModemPlcCreateMessage_Initialize)(void); int (*ModemPlcCreateMessage_Output)(void *, void *, int, int); int (*ModemPlcCreateMessage_Terminate)(void *);

/* Implementacin de funciones. */ /* Funcin mdlInitializeSizes: Establece las dimensiones de las entradas y salidas del bloque Simulink y la cantidad de parmetros que requiere. */ static void mdlInitializeSizes(SimStruct *S) { /* Inicializa dimensiones de entradas y salidas. */

FernandoArielBeunza79156

751

Tesis de Grado en Ingeniera Informtica


DECL_AND_INIT_DIMSINFO(inputDimsInfo); DECL_AND_INIT_DIMSINFO(outputDimsInfo); /* Define la cantidad de parmetros que requiere el bloque Simulink. */ ssSetNumSFcnParams(S, 2); if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) return; /* Define la cantidad de entradas que requiere el bloque Simulink. */ if (!ssSetNumInputPorts(S, 2)) return; ssSetInputPortWidth(S, 0, 1); ssSetInputPortDirectFeedThrough(S, 0, 1); ssSetInputPortRequiredContiguous(S, 0, 1); ssSetInputPortWidth(S, 1, 1); ssSetInputPortDirectFeedThrough(S, 1, 1); ssSetInputPortRequiredContiguous(S, 1, 1); /* Define la cantidad de salidas que requiere el bloque Simulink. */ if (!ssSetNumOutputPorts(S, 2)) return; ssSetOutputPortWidth(S, 0, 1); ssSetOutputPortWidth(S, 1, 1); ssSetNumSampleTimes(S, 1); ssSetNumRWork(S, DYNAMICALLY_SIZED); ssSetNumIWork(S, DYNAMICALLY_SIZED); ssSetNumPWork(S, DYNAMICALLY_SIZED); ssSetNumModes(S, DYNAMICALLY_SIZED); /* */ ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE); } /* Funcin mdlInitializeSampleTimes: Establece el tiempo de muestreo utilizado durante la simulacin. */ static void mdlInitializeSampleTimes(SimStruct *S) { /* Variables. */ struct HINSTANCE__ *hlib;

/* Manejador de biblioteca dinmica. */

/* Establece el tiempo de muestreo. */ ssSetSampleTime(S, 0, 0.0); ssSetOffsetTime(S, 0, 0.0); /* Carga la biblioteca. */ msg = NULL; hlib = NULL; ModemPlcCreateMessage_Initialize = NULL; ModemPlcCreateMessage_Output = NULL; ModemPlcCreateMessage_Terminate = NULL; hlib = LoadLibrary("MODPLC_SIMULINK"); if (!hlib) return; ModemPlcCreateMessage_Initialize = (void * (*)(void)) GetProcAddress(hlib, "ModemPlcCreateMessage_Initialize"); ModemPlcCreateMessage_Output = (int (*)(void *, void *, int, int)) GetProcAddress(hlib, "ModemPlcCreateMessage_Output"); ModemPlcCreateMessage_Terminate = (int (*)(void *)) GetProcAddress(hlib, "ModemPlcCreateMessage_Terminate"); if ((!ModemPlcCreateMessage_Initialize) || (!ModemPlcCreateMessage_Output) || (!ModemPlcCreateMessage_Terminate)) return; /* Inicializa el bloque Simulink. */ grpid = (int) ceil(*mxGetPr(ssGetSFcnParam(S, 0))); msgid = (int) ceil(*mxGetPr(ssGetSFcnParam(S, 1))); msg = ModemPlcCreateMessage_Initialize(); } /* Funcin mdlOutputs: Devuelve el resultado de la ejecucin de un ciclo de simulacin del bloque

752

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


Simulink. */ static void mdlOutputs(SimStruct *S, int_T tid) { /* Variables. */ int *flag_in;

int *flag_out;

unsigned long int *handle_in; unsigned long int *handle_out;

/* Puntero al indicador de entrada de ejecucin de la presente operacin. */ /* Puntero al indicador de salida de ejecucin de la presente operacin. */ /* Puntero al manejador de conexin de entrada. */ /* Puntero al manejador de conexin de salida. */

/* Carga entradas del bloque Simulink. */ handle_in = (unsigned long int *) ssGetInputPortSignal(S, 0); flag_in = (int *) ssGetInputPortSignal(S, 1); /* Carga salidas del bloque Simulink. */ handle_out = (unsigned long int *) ssGetOutputPortSignal(S, 0); flag_out = (int *) ssGetOutputPortSignal(S, 1); /* Ejecuta un ciclo Simulink. */ while(1) { /* Verifica si se solicita ejecutar un ciclo de la presente operacin. */ if (!(*flag_in)) break; /* Verifica que exista el manejador de conexin. */ if (!(*handle_in)) break; /* Ejecuta un ciclo Simulink. */ if (!ModemPlcCreateMessage_Output((void *) *handle_in, msg, grpid, msgid)) break; /* Devuelve el manejador de comunicacin entre bloques Simulink del Modem PLC. */ *handle_out = *handle_in; *flag_out = 1; return; } /* No se pudo ejecutar el ciclo de simulacin. */ *handle_out = 0; *flag_out = 0; } /* Funcin mdlTerminate: Finaliza la ejecucin de la simulacin del bloque Simulink. */ static void mdlTerminate(SimStruct *S) { ModemPlcCreateMessage_Terminate(msg); }

/* Definido por Simulink. */ #ifdef MATLAB_MEX_FILE #include "simulink.c" #else #include "cg_sfun.h" #endif

FernandoArielBeunza79156

753

Tesis de Grado en Ingeniera Informtica

E.3.4. Archivo MODEM_PLC_PUT_FIELD.C


/* MODEM_PLC_PUT_FIELD.C: Se encarga de agregar un campo de datos a un mensaje. */ /* Especifica el nombre de la S-Function. */ #define S_FUNCTION_NAME #define S_FUNCTION_LEVEL

Modem_PLC_Put_Field 2

/* Archivos includos necesarios. */ #include <windows.h> #include <math.h> #include "simstruc.h" #include "tmwtypes.h" #if defined(MATLAB_MEX_FILE) #include "mex.h" #endif

/* Variables globales. */ static int type;

/* Identificador de tipo de dato. */

/* Declaracin de funciones externas. */ void * (*ModemPlcPutField_Initialize)(void); int (*ModemPlcPutField_Output)(void *, int, int, double *); int (*ModemPlcPutField_Terminate)(void);

/* Implementacin de funciones. */ /* Funcin mdlInitializeSizes: Establece las dimensiones de las entradas y salidas del bloque Simulink y la cantidad de parmetros que requiere. */ static void mdlInitializeSizes(SimStruct *S) { /* Inicializa dimensiones de entradas y salidas. */ DECL_AND_INIT_DIMSINFO(inputDimsInfo); DECL_AND_INIT_DIMSINFO(outputDimsInfo); /* Define la cantidad de parmetros que requiere el bloque Simulink. */ ssSetNumSFcnParams(S, 1); if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) return; /* Define la cantidad de entradas que requiere el bloque Simulink. */ if (!ssSetNumInputPorts(S, 3)) return; ssSetInputPortWidth(S, 0, 1); ssSetInputPortDirectFeedThrough(S, 0, 1); ssSetInputPortRequiredContiguous(S, 0, 1); ssSetInputPortWidth(S, 1, 1); ssSetInputPortDirectFeedThrough(S, 1, 1); ssSetInputPortRequiredContiguous(S, 1, 1); ssSetInputPortWidth(S, 2 , DYNAMICALLY_SIZED); ssSetInputPortDirectFeedThrough(S, 2, 1); /* Define la cantidad de salidas que requiere el bloque Simulink. */ if (!ssSetNumOutputPorts(S, 2)) return; ssSetOutputPortWidth(S, 0, 1); ssSetOutputPortWidth(S, 1, 1); ssSetNumSampleTimes(S, 1); ssSetNumRWork(S, DYNAMICALLY_SIZED); ssSetNumIWork(S, DYNAMICALLY_SIZED); ssSetNumPWork(S, DYNAMICALLY_SIZED);

754

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


ssSetNumModes(S, DYNAMICALLY_SIZED); /* */ ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE); } /* Funcin mdlInitializeSampleTimes: Establece el tiempo de muestreo utilizado durante la simulacin. */ static void mdlInitializeSampleTimes(SimStruct *S) { /* Variables. */ struct HINSTANCE__ *hlib;

/* Manejador de biblioteca dinmica. */

/* Establece el tiempo de muestreo. */ ssSetSampleTime(S, 0, 0.0); ssSetOffsetTime(S, 0, 0.0); /* Carga la biblioteca. */ hlib = NULL; ModemPlcPutField_Initialize = NULL; ModemPlcPutField_Output = NULL; ModemPlcPutField_Terminate = NULL; hlib = LoadLibrary("MODPLC_SIMULINK"); if (!hlib) return; ModemPlcPutField_Initialize = (void * (*)(void)) GetProcAddress(hlib, "ModemPlcPutField_Initialize"); ModemPlcPutField_Output = (int (*)(void *, int, int, double *)) GetProcAddress(hlib, "ModemPlcPutField_Output"); ModemPlcPutField_Terminate = (int (*)(void)) GetProcAddress(hlib, "ModemPlcPutField_Terminate"); if ((!ModemPlcPutField_Initialize) || (!ModemPlcPutField_Output) || (!ModemPlcPutField_Terminate)) return; /* Inicializa el bloque Simulink. */ type = (int) ceil(*mxGetPr(ssGetSFcnParam(S, 0))); ModemPlcPutField_Initialize(); } /* Funcin mdlOutputs: Devuelve el resultado de la ejecucin de un ciclo de simulacin del bloque Simulink. */ static void mdlOutputs(SimStruct *S, int_T tid) { /* Variables. */ InputRealPtrsType data_in; int *flag_in;

int *flag_out;

unsigned long int *handle_in; unsigned long int *handle_out;

/* Datos de entrada. */ /* Puntero al indicador de entrada de ejecucin de la presente operacin. */ /* Puntero al indicador de salida de ejecucin de la presente operacin. */ /* Puntero al manejador de conexin de entrada. */ /* Puntero al manejador de conexin de salida. */

/* Carga entradas del bloque Simulink. */ handle_in = (unsigned long int *) ssGetInputPortSignal(S, 0); flag_in = (int *) ssGetInputPortSignal(S, 1); if (ssGetInputPortRequiredContiguous(S, 2)) data_in = &ssGetInputPortRealSignal(S, 2); else data_in = ssGetInputPortRealSignalPtrs(S, 2);

FernandoArielBeunza79156

755

Tesis de Grado en Ingeniera Informtica


/* Carga salidas del bloque Simulink. */ handle_out = (unsigned long int *) ssGetOutputPortSignal(S, 0); flag_out = (int *) ssGetOutputPortSignal(S, 1); /* Ejecuta un ciclo Simulink. */ while(1) { /* Verifica si se solicita ejecutar un ciclo de la presente operacin. */ if (!(*flag_in)) break; /* Verifica que exista el manejador de conexin. */ if (!(*handle_in)) break; /* Ejecuta un ciclo Simulink. */ if (!ModemPlcPutField_Output((void *) *handle_in, type, (unsigned char) ssGetInputPortWidth(S, 2), (double *) *data_in)) break; /* Devuelve el manejador de comunicacin entre bloques Simulink del Modem PLC. */ *handle_out = *handle_in; *flag_out = 1; return; } /* No se pudo ejecutar el ciclo de simulacin. */ *handle_out = 0; *flag_out = 0; } /* Funcin mdlTerminate: Finaliza la ejecucin de la simulacin del bloque Simulink. */ static void mdlTerminate(SimStruct *S) { ModemPlcPutField_Terminate(); }

/* Definido por Simulink. */ #ifdef MATLAB_MEX_FILE #include "simulink.c" #else #include "cg_sfun.h" #endif

E.3.5. Archivo MODEM_PLC_SEND_MESSAGE.C


/* MODEM_PLC_SEND_MESSAGE.C: Se encarga de enviar un mensaje. */ /* Especifica el nombre de la S-Function. */ #define S_FUNCTION_NAME #define S_FUNCTION_LEVEL

Modem_PLC_Send_Message 2

/* Archivos includos necesarios. */ #include <windows.h> #include <math.h> #include "simstruc.h" #include "tmwtypes.h" #if defined(MATLAB_MEX_FILE) #include "mex.h" #endif

756

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

/* Declaracin de funciones externas. */ void * (*ModemPlcSendMessage_Initialize)(void); int (*ModemPlcSendMessage_Output)(void *); int (*ModemPlcSendMessage_Terminate)(void);

/* Implementacin de funciones. */ /* Funcin mdlInitializeSizes: Establece las dimensiones de las entradas y salidas del bloque Simulink y la cantidad de parmetros que requiere. */ static void mdlInitializeSizes(SimStruct *S) { /* Inicializa dimensiones de entradas y salidas. */ DECL_AND_INIT_DIMSINFO(inputDimsInfo); DECL_AND_INIT_DIMSINFO(outputDimsInfo); /* Define la cantidad de parmetros que requiere el bloque Simulink. */ ssSetNumSFcnParams(S, 0); if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) return; /* Define la cantidad de entradas que requiere el bloque Simulink. */ if (!ssSetNumInputPorts(S, 2)) return; ssSetInputPortWidth(S, 0, 1); ssSetInputPortDirectFeedThrough(S, 0, 1); ssSetInputPortRequiredContiguous(S, 0, 1); ssSetInputPortWidth(S, 1, 1); ssSetInputPortDirectFeedThrough(S, 1, 1); ssSetInputPortRequiredContiguous(S, 1, 1); /* Define la cantidad de salidas que requiere el bloque Simulink. */ if (!ssSetNumOutputPorts(S, 2)) return; ssSetOutputPortWidth(S, 0, 1); ssSetOutputPortWidth(S, 1, 1); ssSetNumSampleTimes(S, 1); ssSetNumRWork(S, DYNAMICALLY_SIZED); ssSetNumIWork(S, DYNAMICALLY_SIZED); ssSetNumPWork(S, DYNAMICALLY_SIZED); ssSetNumModes(S, DYNAMICALLY_SIZED); /* */ ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE); } /* Funcin mdlInitializeSampleTimes: Establece el tiempo de muestreo utilizado durante la simulacin. */ static void mdlInitializeSampleTimes(SimStruct *S) { /* Variables. */ struct HINSTANCE__ *hlib;

/* Manejador de biblioteca dinmica. */

/* Establece el tiempo de muestreo. */ ssSetSampleTime(S, 0, 0.0); ssSetOffsetTime(S, 0, 0.0); /* Carga la biblioteca. */ hlib = NULL; ModemPlcSendMessage_Initialize = NULL; ModemPlcSendMessage_Output = NULL; ModemPlcSendMessage_Terminate = NULL; hlib = LoadLibrary("MODPLC_SIMULINK"); if (!hlib) return; ModemPlcSendMessage_Initialize = (void * (*)(void)) GetProcAddress(hlib, "ModemPlcSendMessage_Initialize");

FernandoArielBeunza79156

757

Tesis de Grado en Ingeniera Informtica


ModemPlcSendMessage_Output = (int (*)(void *)) GetProcAddress(hlib, "ModemPlcSendMessage_Output"); ModemPlcSendMessage_Terminate = (int (*)(void)) GetProcAddress(hlib, "ModemPlcSendMessage_Terminate"); if ((!ModemPlcSendMessage_Initialize) || (!ModemPlcSendMessage_Output) || (!ModemPlcSendMessage_Terminate)) return; /* Inicializa el bloque Simulink. */ ModemPlcSendMessage_Initialize(); } /* Funcin mdlOutputs: Devuelve el resultado de la ejecucin de un ciclo de simulacin del bloque Simulink. */ static void mdlOutputs(SimStruct *S, int_T tid) { /* Variables. */ int *flag_in;

int *flag_out;

unsigned long int *handle_in; unsigned long int *handle_out;

/* Puntero al indicador de entrada de ejecucin de la presente operacin. */ /* Puntero al indicador de salida de ejecucin de la presente operacin. */ /* Puntero al manejador de conexin de entrada. */ /* Puntero al manejador de conexin de salida. */

/* Carga entradas del bloque Simulink. */ handle_in = (unsigned long int *) ssGetInputPortSignal(S, 0); flag_in = (int *) ssGetInputPortSignal(S, 1); /* Carga salidas del bloque Simulink. */ handle_out = (unsigned long int *) ssGetOutputPortSignal(S, 0); flag_out = (int *) ssGetOutputPortSignal(S, 1); /* Ejecuta un ciclo Simulink. */ while(1) { /* Verifica si se solicita ejecutar un ciclo de la presente operacin. */ if (!(*flag_in)) break; /* Verifica que exista el manejador de conexin. */ if (!(*handle_in)) break; /* Ejecuta un ciclo Simulink. */ if (!ModemPlcSendMessage_Output((void *) *handle_in)) break; /* Devuelve el manejador de comunicacin entre bloques Simulink del Modem PLC. */ *handle_out = *handle_in; *flag_out = 1; return; } /* No se pudo ejecutar el ciclo de simulacin. */ *handle_out = 0; *flag_out = 0; } /* Funcin mdlTerminate: Finaliza la ejecucin de la simulacin del bloque Simulink. */ static void mdlTerminate(SimStruct *S) {

758

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


ModemPlcSendMessage_Terminate(); }

/* Definido por Simulink. */ #ifdef MATLAB_MEX_FILE #include "simulink.c" #else #include "cg_sfun.h" #endif

E.3.6. Archivo MODEM_PLC_RECEIVE.C


/* MODEM_PLC_RECEIVE_MESSAGE.C: Se encarga de recibir un mensaje. */ /* Especifica el nombre de la S-Function. */ #define S_FUNCTION_NAME #define S_FUNCTION_LEVEL

Modem_PLC_Receive_Message 2

/* Archivos includos necesarios. */ #include <windows.h> #include <math.h> #include "simstruc.h" #include "tmwtypes.h" #if defined(MATLAB_MEX_FILE) #include "mex.h" #endif

/* Variables globales. */ static int grpid; static int msgid; static void *msg;

/* Identificador de grupo. */ /* Identificador de mensaje. */ /* Puntero al mensaje. */

/* Declaracin de funciones externas. */ void * (*ModemPlcReceiveMessage_Initialize)(void); int (*ModemPlcReceiveMessage_Output)(void *, void *, int, int); int (*ModemPlcReceiveMessage_Terminate)(void *);

/* Implementacin de funciones. */ /* Funcin mdlInitializeSizes: Establece las dimensiones de las entradas y salidas del bloque Simulink y la cantidad de parmetros que requiere. */ static void mdlInitializeSizes(SimStruct *S) { /* Inicializa dimensiones de entradas y salidas. */ DECL_AND_INIT_DIMSINFO(inputDimsInfo); DECL_AND_INIT_DIMSINFO(outputDimsInfo); /* Define la cantidad de parmetros que requiere el bloque Simulink. */ ssSetNumSFcnParams(S, 2); if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) return; /* Define la cantidad de entradas que requiere el bloque Simulink. */ if (!ssSetNumInputPorts(S, 2)) return; ssSetInputPortWidth(S, 0, 1); ssSetInputPortDirectFeedThrough(S, 0, 1); ssSetInputPortRequiredContiguous(S, 0, 1); ssSetInputPortWidth(S, 1, 1);

FernandoArielBeunza79156

759

Tesis de Grado en Ingeniera Informtica


ssSetInputPortDirectFeedThrough(S, 1, 1); ssSetInputPortRequiredContiguous(S, 1, 1); /* Define la cantidad de salidas que requiere el bloque Simulink. */ if (!ssSetNumOutputPorts(S, 2)) return; ssSetOutputPortWidth(S, 0, 1); ssSetOutputPortWidth(S, 1, 1); ssSetNumSampleTimes(S, 1); ssSetNumRWork(S, DYNAMICALLY_SIZED); ssSetNumIWork(S, DYNAMICALLY_SIZED); ssSetNumPWork(S, DYNAMICALLY_SIZED); ssSetNumModes(S, DYNAMICALLY_SIZED); /* */ ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE); } /* Funcin mdlInitializeSampleTimes: Establece el tiempo de muestreo utilizado durante la simulacin. */ static void mdlInitializeSampleTimes(SimStruct *S) { /* Variables. */ struct HINSTANCE__ *hlib;

/* Manejador de biblioteca dinmica. */

/* Establece el tiempo de muestreo. */ ssSetSampleTime(S, 0, 0.0); ssSetOffsetTime(S, 0, 0.0); /* Carga la biblioteca. */ msg = NULL; hlib = NULL; ModemPlcReceiveMessage_Initialize = NULL; ModemPlcReceiveMessage_Output = NULL; ModemPlcReceiveMessage_Terminate = NULL; hlib = LoadLibrary("MODPLC_SIMULINK"); if (!hlib) return; ModemPlcReceiveMessage_Initialize = (void * (*)(void)) GetProcAddress(hlib, "ModemPlcReceiveMessage_Initialize"); ModemPlcReceiveMessage_Output = (int (*)(void *, void *, int, int)) GetProcAddress(hlib, "ModemPlcReceiveMessage_Output"); ModemPlcReceiveMessage_Terminate = (int (*)(void *)) GetProcAddress(hlib, "ModemPlcReceiveMessage_Terminate"); if ((!ModemPlcReceiveMessage_Initialize) || (!ModemPlcReceiveMessage_Output) || (!ModemPlcReceiveMessage_Terminate)) return; /* Inicializa el bloque Simulink. */ grpid = (int) ceil(*mxGetPr(ssGetSFcnParam(S, 0))); msgid = (int) ceil(*mxGetPr(ssGetSFcnParam(S, 1))); msg = ModemPlcReceiveMessage_Initialize(); } /* Funcin mdlOutputs: Devuelve el resultado de la ejecucin de un ciclo de simulacin del bloque Simulink. */ static void mdlOutputs(SimStruct *S, int_T tid) { /* Variables. */ int *flag_in;

int *flag_out;

unsigned long int *handle_in;

/* Puntero al indicador de entrada de ejecucin de la presente operacin. */ /* Puntero al indicador de salida de ejecucin de la presente operacin. */ /* Puntero al manejador de conexin

760

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


unsigned long int *handle_out; de entrada. */ /* Puntero al manejador de conexin de salida. */

/* Carga entradas del bloque Simulink. */ handle_in = (unsigned long int *) ssGetInputPortSignal(S, 0); flag_in = (int *) ssGetInputPortSignal(S, 1); /* Carga salidas del bloque Simulink. */ handle_out = (unsigned long int *) ssGetOutputPortSignal(S, 0); flag_out = (int *) ssGetOutputPortSignal(S, 1); /* Ejecuta un ciclo Simulink. */ while(1) { /* Verifica si se solicita ejecutar un ciclo de la presente operacin. */ if (!(*flag_in)) break; /* Verifica que exista el manejador de conexin. */ if (!(*handle_in)) break; /* Ejecuta un ciclo Simulink. */ if (!ModemPlcReceiveMessage_Output((void *) *handle_in, msg, grpid, msgid)) break; /* Devuelve el manejador de comunicacin entre bloques Simulink del Modem PLC. */ *handle_out = *handle_in; *flag_out = 1; return; } /* No se pudo ejecutar el ciclo de simulacin. */ *handle_out = 0; *flag_out = 0; } /* Funcin mdlTerminate: Finaliza la ejecucin de la simulacin del bloque Simulink. */ static void mdlTerminate(SimStruct *S) { ModemPlcReceiveMessage_Terminate(msg); }

/* Definido por Simulink. */ #ifdef MATLAB_MEX_FILE #include "simulink.c" #else #include "cg_sfun.h" #endif

E.3.7. Archivo MODEM_PLC_GET_FIELD.C


/* MODEM_PLC_GET_FIELD.C: Se encarga de extraer un campo de datos a un mensaje. */ /* Especifica el nombre de la S-Function. */ #define S_FUNCTION_NAME #define S_FUNCTION_LEVEL

Modem_PLC_Get_Field 2

FernandoArielBeunza79156

761

Tesis de Grado en Ingeniera Informtica


/* Archivos includos necesarios. */ #include <windows.h> #include <math.h> #include "simstruc.h" #include "tmwtypes.h" #if defined(MATLAB_MEX_FILE) #include "mex.h" #endif

/* Variables globales. */ static int count;

/* Cantidad de datos del campo. */

/* Declaracin de funciones externas. */ void * (*ModemPlcGetField_Initialize)(void); int (*ModemPlcGetField_Output)(void *, unsigned char, double *); int (*ModemPlcGetField_Terminate)(void);

/* Implementacin de funciones. */ /* Funcin mdlInitializeSizes: Establece las dimensiones de las entradas y salidas del bloque Simulink y la cantidad de parmetros que requiere. */ static void mdlInitializeSizes(SimStruct *S) { /* Inicializa dimensiones de entradas y salidas. */ DECL_AND_INIT_DIMSINFO(inputDimsInfo); DECL_AND_INIT_DIMSINFO(outputDimsInfo); /* Define la cantidad de parmetros que requiere el bloque Simulink. */ ssSetNumSFcnParams(S, 1); if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) return; /* Define la cantidad de entradas y salidas que requiere el bloque Simulink. */ if (!ssSetNumInputPorts(S, 2)) return; ssSetInputPortWidth(S, 0, 1); ssSetInputPortDirectFeedThrough(S, 0, 1); ssSetInputPortRequiredContiguous(S, 0, 1); ssSetInputPortWidth(S, 1, 1); ssSetInputPortDirectFeedThrough(S, 1, 1); ssSetInputPortRequiredContiguous(S, 1, 1); if (!ssSetNumOutputPorts(S, 3)) return; ssSetOutputPortWidth(S, 0, 1); ssSetOutputPortWidth(S, 1, 1); ssSetOutputPortWidth(S, 2, (int) ceil(*mxGetPr(ssGetSFcnParam(S, 0)))); ssSetNumSampleTimes(S, 1); ssSetNumRWork(S, DYNAMICALLY_SIZED); ssSetNumIWork(S, DYNAMICALLY_SIZED); ssSetNumPWork(S, DYNAMICALLY_SIZED); ssSetNumModes(S, DYNAMICALLY_SIZED); /* */ ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE); } /* Funcin mdlInitializeSampleTimes: Establece el tiempo de muestreo utilizado durante la simulacin. */ static void mdlInitializeSampleTimes(SimStruct *S) { /* Variables. */ struct HINSTANCE__ *hlib;

/* Manejador de biblioteca dinmica. */

762

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Establece el tiempo de muestreo. */ ssSetSampleTime(S, 0, 0.0); ssSetOffsetTime(S, 0, 0.0); /* Carga la biblioteca. */ hlib = NULL; ModemPlcGetField_Initialize = NULL; ModemPlcGetField_Output = NULL; ModemPlcGetField_Terminate = NULL; hlib = LoadLibrary("MODPLC_SIMULINK"); if (!hlib) return; ModemPlcGetField_Initialize = (void * (*)(void)) GetProcAddress(hlib, "ModemPlcGetField_Initialize"); ModemPlcGetField_Output = (int (*)(void *, unsigned char, double *)) GetProcAddress(hlib, "ModemPlcGetField_Output"); ModemPlcGetField_Terminate = (int (*)(void)) GetProcAddress(hlib, "ModemPlcGetField_Terminate"); if ((!ModemPlcGetField_Initialize) || (!ModemPlcGetField_Output) || (!ModemPlcGetField_Terminate)) return; /* Inicializa el bloque Simulink. */ count = (int) ceil(*mxGetPr(ssGetSFcnParam(S, 0))); ModemPlcGetField_Initialize(); } /* Funcin mdlOutputs: Devuelve el resultado de la ejecucin de un ciclo de simulacin del bloque Simulink. */ static void mdlOutputs(SimStruct *S, int_T tid) { /* Variables. */ int *flag_in;

int *flag_out;

unsigned long int *handle_in; unsigned long int *handle_out; real_T *data_out;

/* Puntero al indicador de entrada de ejecucin de la presente operacin. */ /* Puntero al indicador de salida de ejecucin de la presente operacin. */ /* Puntero al manejador de conexin de entrada. */ /* Puntero al manejador de conexin de salida. */ /* Datos de salida. */

/* Carga entradas del bloque Simulink. */ handle_in = (unsigned long int *) ssGetInputPortSignal(S, 0); flag_in = (int *) ssGetInputPortSignal(S, 1); /* Carga salidas del bloque Simulink. */ handle_out = (unsigned long int *) ssGetOutputPortSignal(S, 0); flag_out = (int *) ssGetOutputPortSignal(S, 1); data_out = (real_T *) ssGetOutputPortRealSignal(S, 2); /* Ejecuta un ciclo Simulink. */ while(1) { /* Verifica si se solicita ejecutar un ciclo de la presente operacin. */ if (!(*flag_in)) break; /* Verifica que exista el manejador de conexin. */ if (!(*handle_in)) break; /* Ejecuta un ciclo Simulink. */ if (!ModemPlcGetField_Output((void *) *handle_in, (unsigned char) count, data_out)) break;

FernandoArielBeunza79156

763

Tesis de Grado en Ingeniera Informtica


/* Devuelve el manejador de comunicacin entre bloques Simulink del Modem PLC. */ *handle_out = *handle_in; *flag_out = 1; return; } /* No se pudo ejecutar el ciclo de simulacin. */ *handle_out = 0; *flag_out = 0; } /* Funcin mdlTerminate: Finaliza la ejecucin de la simulacin del bloque Simulink. */ static void mdlTerminate(SimStruct *S) { ModemPlcGetField_Terminate(); }

/* Definido por Simulink. */ #ifdef MATLAB_MEX_FILE #include "simulink.c" #else #include "cg_sfun.h" #endif

E.3.8. Archivo MODEM_PLC_REAL_TIME.C


/* MODEM_PLC_REAL_TIME.C: Se encarga de minimizar la diferencia entre el tiempo simulacin y el tiempo real transcurrido. */ /* Especifica el nombre de la S-Function. */ #define S_FUNCTION_NAME #define S_FUNCTION_LEVEL

Modem_PLC_Real_Time 2

/* Archivos includos necesarios. */ #include <windows.h> #include <math.h> #include <time.h> #include "simstruc.h" #include "tmwtypes.h" #if defined(MATLAB_MEX_FILE) #include "mex.h" #endif

/* Variables globales. */ static int priority_thread; static DWORD priority_process; unsigned long int start_rtime;

/* Prioridad del hilo de ejecucin. */ /* Prioridad del proceso. */ /* Primera muestra de tiempo real transcurrido. */

/* Implementacin de funciones. */ /* Funcin mdlInitializeSizes: Establece las dimensiones de las entradas y salidas del bloque Simulink y la cantidad de parmetros que requiere.

764

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


*/ static void mdlInitializeSizes(SimStruct *S) { /* Inicializa dimensiones de entradas y salidas. */ DECL_AND_INIT_DIMSINFO(inputDimsInfo); DECL_AND_INIT_DIMSINFO(outputDimsInfo); /* Define la cantidad de parmetros que requiere el bloque Simulink. */ ssSetNumSFcnParams(S, 0); if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) return; /* Define la cantidad de entradas que requiere el bloque Simulink. */ if (!ssSetNumInputPorts(S, 0)) return; /* Define la cantidad de salidas que requiere el bloque Simulink. */ if (!ssSetNumOutputPorts(S, 1)) return; ssSetOutputPortWidth(S, 0, 1); ssSetNumSampleTimes(S, 1); ssSetNumRWork(S, DYNAMICALLY_SIZED); ssSetNumIWork(S, DYNAMICALLY_SIZED); ssSetNumPWork(S, DYNAMICALLY_SIZED); ssSetNumModes(S, DYNAMICALLY_SIZED); /* */ ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE); } /* Funcin mdlInitializeSampleTimes: Establece el tiempo de muestreo utilizado durante la simulacin. */ static void mdlInitializeSampleTimes(SimStruct *S) { /* Establece el tiempo de muestreo. */ ssSetSampleTime(S, 0, 0.0); ssSetOffsetTime(S, 0, 0.0); /* Aumenta la prioridad del proceso encargado de la simulacin. */ priority_process = GetPriorityClass(GetCurrentProcess()); priority_thread = GetThreadPriority(GetCurrentThread()); SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); } /* Funcin mdlOutputs: Devuelve el resultado de la ejecucin de un ciclo de simulacin del bloque Simulink. */ static void mdlOutputs(SimStruct *S, int_T tid) { /* Variables. */ LARGE_INTEGER freq; LARGE_INTEGER ticks; unsigned long int rtime; unsigned long int stime; real_T *time_diff;

/* Frecuencia de reloj. */ /* Cantidad de ticks transcurridos. */ /* Tiempo real transcurrido. */ /* Tiempo de simulacin transcurrido. */ /* Puntero a la direrencia entre tiempo de simulacin y tiempo real. */

/* Carga salidas del bloque Simulink. */ time_diff = (real_T *) ssGetOutputPortRealSignal(S, 0); /* Obtiene el tiempo de simulacin transcurrido. */ stime = (unsigned long int) (ssGetT(S) - ssGetTStart(S)) * 1000; /* Obtiene el tiempo real transcurrido con mxima precisin posible. */ ticks.QuadPart = 0;

FernandoArielBeunza79156

765

Tesis de Grado en Ingeniera Informtica


if (QueryPerformanceFrequency(&freq)) { QueryPerformanceCounter(&ticks); rtime = (unsigned long int) ((((double) (ticks.QuadPart)) * 1000) / freq.QuadPart); } else rtime = (unsigned long int) (((double) (clock()) / CLOCKS_PER_SEC) * 1000); if (stime) rtime -= start_rtime; else { start_rtime = rtime; rtime = 0; } /* Minimiza la diferencia entre el tiempo simulacin y el tiempo real transcurrido. */ if (stime > rtime) { Sleep(stime - rtime); *time_diff = (real_T) (stime - rtime); } else *time_diff = -((real_T) (rtime - stime)); } /* Funcin mdlTerminate: Finaliza la ejecucin de la simulacin del bloque Simulink. */ static void mdlTerminate(SimStruct *S) { SetPriorityClass(GetCurrentProcess(), priority_process); SetThreadPriority(GetCurrentThread(), priority_thread); }

/* Definido por Simulink. */ #ifdef MATLAB_MEX_FILE #include "simulink.c" #else #include "cg_sfun.h" #endif

766

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Apndice F: Implementacin del dispositivo cliente


En el ste apndice se describe y detalla la implementacin del dispositivo cliente utilizado para evaluar el funcionamiento del modem PLC. La implementacin incluye tanto el hardware que conforma al dispositivo cliente como el cdigo fuente asociado al firmware del mismo.

F.1. Descripcin del dispositivo


El dispositivo cliente tiene la funcin de transformar los mensajes que viajan por medio de la red PLC en acciones concretas. Dicho dispositivo posee una interfaz de comunicacin con la que se conecta al modem PLC, y por la cual recibe y enva mensajes; una entrada de alimentacin que se conecta a la alimentacin provista por el modem PLC, utilizada para alimentar los circuitos del dispositivo cliente; y una entrada de alimentacin auxiliar que se conecta directamente a la red, destinada a proporcionar energa a los bloques de potencia del dispositivo cliente. Para poder transformar los mensajes en acciones concretas, el dispositivo cliente posee un microcontrolador encargado de recibir los mensajes, y segn el contenido de los mismos, ejecutar las acciones asociadas a dichos mensajes. En el caso particular del dispositivo implementado, las acciones se reducen al encendido y apagado de tres luces. Tambin, el dispositivo cliente cuenta con la posibilidad de detectar fallas en los focos de iluminacin antes de ser encendidos, a modo de generar y enviar mensajes a otros dispositivos reportando la falla. El dispositivo cliente fue diseado para proveer las mnimas funcionalidades a modo de probar el funcionamiento de las red PLC, y de los modems conectados a sta ltima.

F.2. Implementacin del dispositivo


A continuacin se detalla el esquema del dispositivo cliente en donde se muestran cada uno de los componentes descriptos con anterioridad. En la primer pgina se pueden observar la fuente de alimentacin, la interfaz de comunicacin con el mdulo de procesamiento. En la segunda pgina se puede observar el microcontrolador junto a su reloj. Por ltimo en la tercer pgina se puede observar los bloques de control de potencia.

FernandoArielBeunza79156

767

Tesis de Grado en Ingeniera Informtica

768

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

FernandoArielBeunza79156

769

Tesis de Grado en Ingeniera Informtica

770

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

F.3. Cdigo fuente


EL cdigo fuente del dispositivo cliente consta de un solo archivo denominado client_device.c que se detalla a continuacin:
/* client_device: Firmware del dispositivo cliente. */

/* Archivos includos necesarios. */ #define MODPLCAP_MSGSIZE 9 #include <stdio.h> #include <at89x52.h> #include "modplcap.h"

/* Definicin de SFR necesarias. */ __sfr __at (0xa7) WDTPRG; __sfr __at (0xa6) WDTRST;

/* Configuracin del watchdog. */ /* Control del watchdog. */

/* Variables globales. */ /* Estado de las luces. */ unsigned char lights; /* Posicin de las luces. */ unsigned char side; /* Buffer de mensajes recibidos. */ modplcap_msg buffer;

/* Funcin func: Procesa los mensajes recibidos por medio de la conexin. */ void func(__data modplcap_hd *hd, __data modplcap_msg *msg, __data void *param) __reentrant { /* Variables. */ modplcap_msg rmsg; /* Mensaje de respuesta. */ modplcap_ftype type; /* Tipo de parmetro. */ modplcap_msgid msgid; /* Identificador de mensaje. */ unsigned char val; /* Parmetro. */ unsigned char port; /* Puerto. */ unsigned char count; /* Multiplicidad del parmetro. */

/* Apaga todas las luces. */ port = P1; P1 = 0xf8; /* Procesa mensaje. */ while(1) { /* Recibe el mensaje. */ msgid = modplcap_getmsgid(msg); modplcap_getfield(msg, &type, &count, &val); /* Crea un mensaje de respuesta. */ modplcap_newmsg(hd, &rmsg, 0x02, 0x8001); /* Verificacin de estado de focos de iluminacin. */ if (msgid == 0x8000)

FernandoArielBeunza79156

771

Tesis de Grado en Ingeniera Informtica


{ val = 0x00; if (!(P3 & 0x08)) val |= if (!(P3 & 0x08)) val |= if (!((P3 & 0x10) || (P3 if (!(P3 & 0x20)) val |= modplcap_putfield(&rmsg, } /* Encendido/apagado de luz de guio derecho. */ else if ((msgid == 0x8001) && (side)) { lights &= 0xf7; if (val) lights |= 0x08; } /* Encendido/apagado de luz de guio izquierdo. */ else if ((msgid == 0x8002) && (!side)) { lights &= 0xf7; if (val) lights |= 0x08; } /* Encendido/apagado de luces de posicin, bajas y altas. */ else if (msgid == 0x8003) { lights &= 0xf8; lights |= (val & 0x07); } /* Identificador de mensaje desconocido. */ else break; /* Devuelve estado de las luces. */ if ((msgid >= 0x8001) && (msgid <= 0x8003)) modplcap_putfield(&rmsg, MODPLCAP_UINT8TYPE, 1, &lights); /* Enva respuesta. */ modplcap_sendmsg(&rmsg); break; } /* Reestrablece el estado original de las luces. */ P1 = port; param; } 0x01; 0x02; & 0x08))) val |= 0x04; 0x08; MODPLCAP_UINT8TYPE, 1, &val);

/* Funcin main: Funcin principal. */ void main(void) { /* Variables. */ unsigned short i; __data modplcap_hd *hd;

/* Contador. */ /* Manejador de conexin. */

/* P1 P0 P2 P3

Inicializa puertos. */ = 0xf8; = 0xff; = 0xff; = 0xff;

/* Inicializa el estado de las luces. */ lights = 0x00; side = (P1 >> 3) & 0x01; /* Ciclo de ejecucin. */

772

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


while(1) { /* hd if if if if if

Inicializa la conexin. */ = modplcap_init(1); (!hd) break; (!modplcap_setbuffer(hd, &buffer)) break; (!modplcap_notify(hd, func, NULL)) break; (!modplcap_publish(hd, 2)) break; (!modplcap_subscribe(hd, 1)) break;

/* Actualiza estado de las luces. */ i = 0; while(1) { /* Verifica el estado del dispositivo. */ if (!i) { if (!modplcap_status(hd)) break; } /* Actualiza estado de luz de guio. */ if (lights & 0x08) { if (!(i & 0x7fff)) P1 = (P1 & 0xfb) | ((P1 ^ 0x04) & 0x04); } else P1 &= 0xfb; /* Actualiza estado de luces de posicin, bajas y altas. */ switch(lights & 0x07) { /* Luces apagadas. */ case 0x00: P1 &= 0xfc; break; /* Luces de posicin. */ case 0x01: P1 &= 0xfc; if (P3 & 0x08) break; if (!(i & 0x0001)) P1 |= ((P1 ^ 0x01) & 0x01); break; /* Luces bajas. */ case 0x02: P1 &= 0xfc; if (P3 & 0x08) break; P1 |= 0x01; break; /* Luces altas. */ case 0x03: P1 &= 0xfc; if ((P3 & 0x10) || (P3 & 0x08)) break; P1 |= 0x03; break; /* Otra configuracin. */ default: break; } /* Actualiza contador. */ i ++; } /* Finaliza la conexin. */ modplcap_leave(hd, 2); modplcap_leave(hd, 1); modplcap_release(hd); break;

FernandoArielBeunza79156

773

Tesis de Grado en Ingeniera Informtica


} /* Fuerza el reinicio del dispositivo. */ P1 = 0xf8; WDTPRG = 0x07; WDTRST = 0x1e; WDTRST = 0xe1; while(1); }

774

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Apndice G: Implementacin de pruebas


En el presente apndice se realiza la descripcin y el detalle de las implementaciones de las aplicaciones de prueba destinadas a evaluar el funcionamiento del modem PLC. Las implementaciones se especifican por medio del cdigo fuente correspondiente tanto a la plataforma Windows como Linux.

G.1. Descripcin
Para evaluar el funcionamiento del sistema propuesto en el presente trabajo se implementa una red compuesta por dos modems PLC, un dispositivo cliente real y un dispositivo cliente virtual. El dispositivo cliente real se conecta a uno de los modems, mientras que el dispositivo cliente virtual consiste en una aplicacin que se ejecuta en una PC que se conecta al otro modem. Gracias a que el driver de la interfaz RS232 (ver Apndice C) presenta una funcin de depuracin que permite ver el trfico de mensajes, y a que el modem PLC por medio de una conexin especial permite visualizar por medio de una PC el trfico de mensajes entre el dispositivo cliente real y el modem PLC; no es necesario implementar un dispositivo especial de diagnstico (que requerira de otro modem PLC), ni una aplicacin de diagnstico corriendo en paralelo al la aplicacin que simula al dispositivo cliente virtual en la PC, para supervisar el funcionamiento de la red de prueba. La evaluacin al sistema se realiza a dos niveles: nivel capa fsica y nivel capa de aplicacin. El objetivo de la evaluacin a nivel de capa fsica es evaluar el desempeo de los aspectos fsicos de los modems PLC implementados. En cambio, la evaluacin a nivel de capa de aplicacin se concentra en evaluar el comportamiento del sistema desarrollado en forma conjunta. Para realizar la evaluacin a nivel de capa fsica se desarrolla una aplicacin de prueba que permite determinar la tasa de bits errados y la calidad del canal de comunicacin. Las aplicaciones de prueba para evaluar el sistema a nivel de capa de aplicacin corresponden a los dispositivos clientes virtuales. Una de las aplicaciones de prueba consiste en un modelo Simulink, la otra consiste en una aplicacin desarrollada en lenguaje C y C++ para plataforma Windows y Linux.

G.2. Red de prueba implementada


Como se mencion con anterioridad, para la realizacin de las distintas pruebas se utiliza una red compuesta por dos modems PLC, un dispositivo cliente real, una PC; adems de ciertos componentes como una fuente de alimentacin para simular una batera y un filtro de rechazo de banda para que la fuente de alimentacin no absorba la seal de informacin. La composicin de la red puede observarse en la figura G1.

FernandoArielBeunza79156

775

Tesis de Grado en Ingeniera Informtica

Figura G1. Red implementada.

Como se puede ver en la figura anterior, a la derecha se puede observar el dispositivo cliente real junto con su modem PLC. A la izquierda, hacia el fondo, se puede observar el otro modem PLC que se conecta a la PC. A la izquierda, hacia adelante se puede observar la fuente de alimentacin que simula la batera conectada al filtro de rechazo de banda. ste filtro de rechazo de banda puede observarse ms en detalle en la figura G2.

Figura G2. Filtro de rechazo de banda.

El filtro de rechazo de banda simplemente consiste en un inductor cuya funcin es bloquear el paso de la seal de informacin emitida por los modems PLC hacia la fuente de alimentacin. En la figura G3 se puede observar el dispositivo cliente real (izquierda) conectado uno de los modems PLC (derecha). El dispositivo cliente es alimentado en parte por la energa proveniente 776 FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica directamente de la lnea y tambin por el modem PLC (que tiene capacidad de suministrar una alimentacin limitada). La transferencia de datos entre el dispositivo cliente y el modem PLC se lleva a cabo por medio de tres conductores (TX, RX y GND). La interfaz RS232 que posee el modem PLC se encuentra conectada para poder visualizar por medio de una PC las comunicaciones entre el dispositivo cliente y el modem PLC.

Figura G3. Modem PLC conectado al dispositivo cliente.

En la figura G4 se puede observar el modem PLC conectado a la PC donde se ejecuta la aplicacin que implementa al dispositivo cliente virtual. Las comunicaciones entre la PC y el modem PLC se realizan por medio de la interfaz RS232 que se conecta al puerto serie de la PC (o a un puerto USB por medio de un adaptador, como sucede en ste caso).

Figura G4. Modem PLC conectado a una PC.

FernandoArielBeunza79156

777

Tesis de Grado en Ingeniera Informtica

G.3. Modelo Simulink de prueba


El modelo Simulink que implementa que implementa el dispositivo cliente virtual consiste en una seal generada por el correspondiente bloque funcional, que enciende y apaga uno de los focos del dispositivo cliente virtual por medio del envo de mensajes. El dispositivo cliente real tambin enva un mensaje de respuesta que es recibido y mostrado por el bloque osciloscopio, junto con la seal de activacin original.

Figura G5. Modelo Simulink de prueba.

En la figura G5 se observan todos los bloques funcionales que intervienen en el envo y recepcin de mensajes. En la parte superior, recorriendo de izquierda a derecha, el primer bloque es el encargado de establecer la conexin con el modem PLC, el segundo se encarga de crear un mensaje, el tercero agrega un campo al mensaje creado, el cuarto enva el mensaje hacia el dispositivo cliente real, el quinto recibe un mensaje del dispositivo cliente real, y el ltimo extrae el campo de datos con la informacin recibida del mensaje recibido.

G.4. Aplicaciones C/C++ de prueba


Aqu se detalla el cdigo fuente de cada una de las aplicaciones desarrolladas en lenguaje C y C++ que simulan un dispositivo cliente virtual, utilizadas para evaluar del sistema de comunicacin desarrollado. Dichas aplicaciones de prueba se encuentran implementadas tanto en plataforma Windows como en Linux. A continuacin se mencionan cada uno de los archivos fuente correspondientes a las aplicaciones de prueba:

778

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Archivo testphy.c: en este archivo se encuentran implementadas las pruebas realizadas sobre la capa fsica del modem PLC. Archivo testap.c: en este archivo se encuentra implementado (en lenguaje C) el dispositivo cliente virtual utilizado para realizar pruebas sobre la capa de aplicacin del modem PLC. Archivo testapcpp.cpp: en este archivo se encuentra implementado (en lenguaje C++) el dispositivo cliente virtual utilizado para realizar pruebas sobre la capa de aplicacin del modem PLC.

G.4.1. Plataforma Windows


A continuacin se detalla cada uno de los archivos fuente correspondientes a las aplicaciones de prueba para plataforma Windows.

G.4.1.1. Archivo testphy.c


/* testphy.c: Pruebas de funcionamiento de la capa fsica del modem PLC. */

/* Archivos includos necesarios. */ #include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #include "..\..\..\modem_driver\windows\modplcphy\modplcphy.h"

/* Funcin main. */ int main(int argc, char *argv[]) { /* Variables. */ int port1; int port2; int badframe; size_t i; size_t size; size_t framesize; unsigned long int unsigned long int unsigned long int unsigned long int unsigned long int unsigned long int unsigned long int

c; dist; frames; badbits; lostbits; sentbits; badframes;

unsigned long int lostframes; double difftime; clock_t clock1; clock_t clock2; unsigned char diff;

/* Puerto serie utilizado. */ /* Puerto serie utilizado. */ /* Indicador de trama corrompida. */ /* Contador. */ /* Tamao de trama enviada/recibida. */ /* Tamao de trama. */ /* Contador de ciclos de prueba. */ /* Distancia. */ /* Cantidad de tramas de prueba. */ /* Cantidad de bits errados. */ /* Cantidad de bits perdidos. */ /* Cantidad de bits enviados. */ /* Cantidad de tramas corrompidas. */ /* Cantidad de tramas prdidas. */ /* Diferencia de tiempo. */ /* Tiempo inicial. */ /* Tiempo final. */ /* Diferencia entre bytes. */

FernandoArielBeunza79156

779

Tesis de Grado en Ingeniera Informtica


modplcphy_hd *hd1; modplcphy_hd *hd2; unsigned char *frame1; unsigned char *frame2; /* Manejador de interfaz capa fsica del modem /* Manejador de interfaz capa fsica del modem /* Trama de prueba, */ /* Trama de prueba. */ con la PLC. */ con la PLC. */

/* Carga parmetros. */ if (argc < 4) return -1; port1 = atoi(argv[1]); port2 = atoi(argv[2]); frames = atoi(argv[3]); /* Carga biblioteca. */ if (!modplcphy_loadlib()) return 0; /* Prueba. */ while(1) { /* Inicializa conexiones con capa fsica. */ hd1 = modplcphy_init(port1); if (!hd1) break; hd2 = modplcphy_init(port2); if (!hd2) break; /* Obtiene el tamao mximo de trama. */ framesize = modplcphy_getpayloadsize(hd1, 0); if (framesize > modplcphy_getpayloadsize(hd2, 0)) framesize = modplcphy_getpayloadsize(hd2, 0); /* Reserva memoria para almacenar las tramas de prueba. */ frame1 = (unsigned char *) malloc(sizeof(unsigned char) * framesize); if (!frame1) break; frame2 = (unsigned char *) malloc(sizeof(unsigned char) * framesize); if (!frame2) break; /* Inicializa contadores. */ badbits = 0; lostbits = 0; sentbits = 0; badframes = 0; lostframes = 0; /* Inicia la secuencia pseudoaleatoria. */ srand((unsigned) time(NULL)); /* Prueba de envo y recepcin de tramas. */ for(c = 1; c <= frames; c++) { /* Genera trama de prueba. */ printf("ciclo %li - ", c); size = (rand() % framesize) + 1; switch(rand() % 14) { /* Patrn 00000000. */ case 0: printf("patrn 00000000 - "); for(i = 0; i < size; i++) frame1[i] = 0x00; break; /* Patrn 11111111. */ case 1: printf("patrn 11111111 - "); for(i = 0; i < size; i++) frame1[i] = 0xff; break; /* Patrn 01010101. */ case 2: printf("patrn 01010101 - "); for(i = 0; i < size; i++) frame1[i] = 0x55;

780

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


break; /* Patrn 10101010. */ case 3: printf("patrn 10101010 - "); for(i = 0; i < size; i++) frame1[i] = 0xaa; break; /* Patrn 00110011. */ case 4: printf("patrn 00110011 - "); for(i = 0; i < size; i++) frame1[i] = 0x33; break; /* Patrn 11001100. */ case 5: printf("patrn 11001100 - "); for(i = 0; i < size; i++) frame1[i] = 0xcc; break; /* Patrn 01100110. */ case 6: printf("patrn 01100110 - "); for(i = 0; i < size; i++) frame1[i] = 0x66; break; /* Patrn 10011001. */ case 7: printf("patrn 10011001 - "); for(i = 0; i < size; i++) frame1[i] = 0x99; break; /* Patrn 00001111. */ case 8: printf("patrn 00001111 - "); for(i = 0; i < size; i++) frame1[i] = 0x0f; break; /* Patrn 11110000. */ case 9: printf("patrn 11110000 - "); for(i = 0; i < size; i++) frame1[i] = 0xf0; break; /* Patrn 00111100. */ case 10: printf("patrn 00111100 - "); for(i = 0; i < size; i++) frame1[i] = 0x3c; break; /* Patrn 11000011. */ case 11: printf("patrn 11000011 - "); for(i = 0; i < size; i++) frame1[i] = 0xc3; break; /* Patrn secuencia. */ case 12: printf("patrn secuencia - "); for(i = 0; i < size; i++) frame1[i] = (char) (i & 0x00ff); break; /* Patrn aleatorio. */ case 13: printf("patrn aleatorio - "); for(i = 0; i < size; i++) frame1[i] = (char) ((rand() % 256) & 0x00ff); break; } /* Limpia el buffer del receptor. */

FernandoArielBeunza79156

781

Tesis de Grado en Ingeniera Informtica


modplcphy_clrbuffer(hd2, 0); /* Establece el modo captura para el receptor. */ modplcphy_capframe(hd2, 0, size); /* Enva trama de prueba. */ clock1 = clock(); size = modplcphy_sndframe(hd1, 0, frame1, size); if (!size) { badframes ++; continue; } sentbits += (size * 8); /* Recibe trama de prueba. */ if (!modplcphy_poll(hd2, 0)) { printf("%li bits - trama perdida\r\n", size * 8); lostbits += (size * 8); lostframes ++; continue; } size = modplcphy_getframe(hd2, 0, frame2, size); clock2 = clock(); /* Calcula el tiempo entre envo y recepcin. */ difftime = ((double) (clock2 - clock1) / CLOCKS_PER_SEC) * 1000; printf("%li bits - %.1f milisegundos\r\n", size * 8, difftime); /* Cuenta los errores ocurridos. */ badframe = 0; for(i = 0; i < size; i++) { dist = badbits; diff = frame1[i] ^ frame2[i]; if (diff & 0x80) badbits ++; if (diff & 0x40) badbits ++; if (diff & 0x20) badbits ++; if (diff & 0x10) badbits ++; if (diff & 0x08) badbits ++; if (diff & 0x04) badbits ++; if (diff & 0x02) badbits ++; if (diff & 0x01) badbits ++; dist = badbits - dist; if (!dist) continue; badframe = 1; } if (badframe) badframes ++; } /* Imprime resultados de la prueba. */ printf("\r\n"); printf("Bits enviados: %li\r\n", sentbits); printf("Bits perdidos: %li (%.3f%%)\r\n", lostbits, ((double) lostbits / (double) sentbits) * 100); printf("Bits errados: %li (%.3f%%)\r\n", badbits, ((double) badbits / (double) sentbits) * 100); printf("Tramas enviadas: %li\r\n", frames); printf("Tramas prdidas: %li (%.3f%%)\r\n", lostframes, ((double) lostframes / (double) frames) * 100); printf("Tramas corrompidas: %li (%.3f%%)\r\n", badframes, ((double) badframes / (double) frames) * 100); printf("\r\n"); break; }

782

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Libera memoria reservada para almacenar tramas de prueba. */ if (frame2) free(frame2); if (frame1) free(frame1); /* Finaliza las conexiones. */ modplcphy_release(hd2); modplcphy_release(hd1); /* Fin. */ return 0; }

G.4.1.2. Archivo testap.c


/* testap.c: Pruebas de funcionamiento de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include <stdio.h> #include <windows.h> #include "..\..\..\modem_driver\windows\modplcap\modplcap.h"

/* Funcin main. */ int main(int argc, char *argv[]) { /* Variables. */ int port; unsigned char count; unsigned char status; modplcap_ftype type; modplcap_msg msg; modplcap_hd *hd;

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

Puerto serie utilizado. */ Multiplicidad. */ Estado de los faros. */ Tipo de campo. */ Mensaje. */ Manejador de interfaz con la capa de aplicacin del modem PLC. */

/* Carga parmetros. */ if (argc < 2) return -1; port = atoi(argv[1]); /* Carga biblioteca. */ if (!modplcap_loadlib()) return 0; /* Prueba. */ while(1) { /* Inicializa la conexin con capa de aplicacin. */ hd = modplcap_init(port); if (!hd) break; /* Suscripcin a grupos de difusin. */ if (!modplcap_publish(hd, 1)) break; if (!modplcap_subscribe(hd, 2)) break; /* Verifica el estado de los focos. */ printf("Verificacin de estado de focos\r\n\n"); modplcap_newmsg(hd, &msg, 1, 0x8000); modplcap_sendmsg(&msg); modplcap_destroymsg(&msg); if (!modplcap_receivemsg(hd, &msg)) break; modplcap_getfield(&msg, &type, &count, &status); modplcap_destroymsg(&msg);

FernandoArielBeunza79156

783

Tesis de Grado en Ingeniera Informtica


printf("* Estado luz de posicin if (status & 0x01) printf("OK\r\n"); else printf("Falla\r\n"); printf("* Estado luz de baja if (status & 0x02) printf("OK\r\n"); else printf("Falla\r\n"); printf("* Estado luz de alta if (status & 0x04) printf("OK\r\n"); else printf("Falla\r\n"); printf("* Estado luz de guio if (status & 0x08) printf("OK\r\n"); else printf("Falla\r\n"); : ");

: ");

: ");

: ");

/* Encendido de luz de guio derecho. */ printf("\r\nEncendido de luz de guio derecho "); printf("(presione una tecla para continuar)\r\n\n"); getchar(); modplcap_newmsg(hd, &msg, 1, 0x8001); status = 0x01; modplcap_putfield(&msg, MODPLCAP_UINT8TYPE, 1, &status); modplcap_sendmsg(&msg); modplcap_destroymsg(&msg); /* Apagado de luz de guio derecho. */ printf("Apagado de luz de guio derecho "); printf("(presione una tecla para continuar)\r\n\n"); getchar(); modplcap_newmsg(hd, &msg, 1, 0x8001); status = 0x00; modplcap_putfield(&msg, MODPLCAP_UINT8TYPE, 1, &status); modplcap_sendmsg(&msg); modplcap_destroymsg(&msg); /* Encendido de luz de guio izquierdo. */ printf("Encendido de luz de guio izquierdo "); printf("(presione una tecla para continuar)\r\n\n"); getchar(); modplcap_newmsg(hd, &msg, 1, 0x8002); status = 0x01; modplcap_putfield(&msg, MODPLCAP_UINT8TYPE, 1, &status); modplcap_sendmsg(&msg); modplcap_destroymsg(&msg); /* Apagado de luz de guio izquierdo. */ printf("Apagado de luz de guio izquierdo "); printf("(presione una tecla para continuar)\r\n\n"); getchar(); modplcap_newmsg(hd, &msg, 1, 0x8002); status = 0x00; modplcap_putfield(&msg, MODPLCAP_UINT8TYPE, 1, &status); modplcap_sendmsg(&msg); modplcap_destroymsg(&msg); /* Encendido de luces de posicin. */ printf("Encendido de luces de posicin "); printf("(presione una tecla para continuar)\r\n\n"); getchar(); modplcap_newmsg(hd, &msg, 1, 0x8003); status = 0x01; modplcap_putfield(&msg, MODPLCAP_UINT8TYPE, 1, &status); modplcap_sendmsg(&msg); modplcap_destroymsg(&msg);

784

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Encendido de luces bajas. */ printf("Encendido de luces bajas "); printf("(presione una tecla para continuar)\r\n\n"); getchar(); modplcap_newmsg(hd, &msg, 1, 0x8003); status = 0x02; modplcap_putfield(&msg, MODPLCAP_UINT8TYPE, 1, &status); modplcap_sendmsg(&msg); modplcap_destroymsg(&msg); /* Encendido de luces altas. */ printf("Encendido de luces altas "); printf("(presione una tecla para continuar)\r\n\n"); getchar(); modplcap_newmsg(hd, &msg, 1, 0x8003); status = 0x03; modplcap_putfield(&msg, MODPLCAP_UINT8TYPE, 1, &status); modplcap_sendmsg(&msg); modplcap_destroymsg(&msg); /* Apagado de luces de iluminacin. */ printf("Apagado de luz luces de iluminacin "); printf("(presione una tecla para continuar)\r\n\n"); getchar(); modplcap_newmsg(hd, &msg, 1, 0x8003); status = 0x00; modplcap_putfield(&msg, MODPLCAP_UINT8TYPE, 1, &status); modplcap_sendmsg(&msg); modplcap_destroymsg(&msg); break; } /* Finaliza la conexin. */ modplcap_release(hd); /* Fin. */ return 0; }

G.4.1.3. Archivo testapcpp.cpp


/* testapcpp.c: Pruebas de funcionamiento de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include <iostream> #include <windows.h> #include "..\..\..\modem_driver\windows\modplcapcpp\modplcapcpp.h"

using namespace std;

/* Funcin main. */ int main(int argc, char *argv[]) { /* Variables. */ int port; unsigned char count; unsigned char status; modplcapcpp_ftype type; modplcapcpp_msg *msg; modplcapcpp *hd;

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

Puerto serie utilizado. */ Multiplicidad. */ Estado de los faros. */ Tipo de campo. */ Mensaje. */ Manejador de interfaz con la

FernandoArielBeunza79156

785

Tesis de Grado en Ingeniera Informtica


capa de aplicacin del modem PLC. */

/* Carga parmetros. */ if (argc < 2) return -1; port = atoi(argv[1]); /* Prueba. */ while(1) { /* Inicializa la conexin con capa de aplicacin. */ hd = new modplcapcpp(port); if (!hd) break; /* Suscripcin a grupos de difusin. */ if (!hd->publish(1)) break; if (!hd->subscribe(2)) break; /* Verifica el estado de los focos. */ cout << "Verificacin de estado de focos" << endl << endl; msg = new modplcapcpp_msg(hd, 1, 0x8000); if (!msg) break; msg->sendmsg(); delete msg; msg = new modplcapcpp_msg(hd); if (!msg) break; msg->getfield(&type, &count, &status); delete msg; cout << "* Estado luz de posicin : "; if (status & 0x01) cout << "OK" << endl; else cout << "Falla" << endl; cout << "* Estado luz de baja : "; if (status & 0x02) cout << "OK" << endl; else cout << "Falla" << endl; cout << "* Estado luz de alta : "; if (status & 0x04) cout << "OK" << endl; else cout << "Falla" << endl; cout << "* Estado luz de guio : "; if (status & 0x08) cout << "OK" << endl; else cout << "Falla" << endl; /* Encendido de luz de guio derecho. */ cout << endl << "Encendido de luz de guio derecho "; cout << "(presione una tecla para continuar)" << endl << endl; cin.get(); msg = new modplcapcpp_msg(hd, 1, 0x8001); if (!msg) break; status = 0x01; msg->putfield(MODPLCAPCPP_UINT8TYPE, 1, &status); msg->sendmsg(); delete msg; /* Apagado de luz de guio derecho. */ cout << "Apagado de luz de guio derecho "; cout << "(presione una tecla para continuar)" << endl << endl; cin.get(); msg = new modplcapcpp_msg(hd, 1, 0x8001); if (!msg) break; status = 0x00; msg->putfield(MODPLCAPCPP_UINT8TYPE, 1, &status); msg->sendmsg(); delete msg;

786

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


/* Encendido de luz de guio izquierdo. */ cout << "Encendido de luz de guio izquierdo "; cout << "(presione una tecla para continuar)" << endl << endl; cin.get(); msg = new modplcapcpp_msg(hd, 1, 0x8002); if (!msg) break; status = 0x01; msg->putfield(MODPLCAPCPP_UINT8TYPE, 1, &status); msg->sendmsg(); delete msg;; /* Apagado de luz de guio izquierdo. */ cout << "Apagado de luz de guio izquierdo "; cout << "(presione una tecla para continuar)" << endl << endl; cin.get(); msg = new modplcapcpp_msg(hd, 1, 0x8002); if (!msg) break; status = 0x00; msg->putfield(MODPLCAPCPP_UINT8TYPE, 1, &status); msg->sendmsg(); delete msg; /* Encendido de luces de posicin. */ cout << "Encendido de luces de posicin "; cout << "(presione una tecla para continuar)" << endl << endl; cin.get(); msg = new modplcapcpp_msg(hd, 1, 0x8003); if (!msg) break; status = 0x01; msg->putfield(MODPLCAPCPP_UINT8TYPE, 1, &status); msg->sendmsg(); delete msg; /* Encendido de luces bajas. */ cout << "Encendido de luces bajas "; cout << "(presione una tecla para continuar)" << endl << endl; cin.get(); msg = new modplcapcpp_msg(hd, 1, 0x8003); if (!msg) break; status = 0x02; msg->putfield(MODPLCAPCPP_UINT8TYPE, 1, &status); msg->sendmsg(); delete msg; /* Encendido de luces altas. */ cout << "Encendido de luces altas "; cout << "(presione una tecla para continuar)" << endl << endl; cin.get(); msg = new modplcapcpp_msg(hd, 1, 0x8003); if (!msg) break; status = 0x03; msg->putfield(MODPLCAPCPP_UINT8TYPE, 1, &status); msg->sendmsg(); delete msg; /* Apagado de luces de iluminacin. */ cout << "Apagado de luz luces de iluminacin "; cout << "(presione una tecla para continuar)" << endl << endl; cin.get(); msg = new modplcapcpp_msg(hd, 1, 0x8003); if (!msg) break; status = 0x00; msg->putfield(MODPLCAPCPP_UINT8TYPE, 1, &status); msg->sendmsg(); delete msg; break; } /* Finaliza la conexin. */ delete hd;

FernandoArielBeunza79156

787

Tesis de Grado en Ingeniera Informtica


/* Fin. */ return 0; }

G.4.2. Plataforma Linux


A continuacin se detalla cada uno de los archivos fuente correspondientes a las aplicaciones de prueba para plataforma Linux.

G.4.2.1. Archivo testphy.c


/* testphy.c: Pruebas de funcionamiento de la capa fsica del modem PLC. */

/* Archivos includos necesarios. */ #include <stdio.h> #include <stdlib.h> #include <math.h> #include <sys/time.h> #include "../../../modem_driver/linux/modplcphy/modplcphy.h"

/* Funcin main. */ int main(int argc, char *argv[]) { /* Variables. */ int port1; int port2; int badframe; size_t i; size_t size; size_t framesize; unsigned long int unsigned long int unsigned long int unsigned long int unsigned long int unsigned long int unsigned long int

c; dist; frames; badbits; lostbits; sentbits; badframes;

unsigned long int lostframes; double difftime; struct timeval time1; struct timeval time2; unsigned char diff; modplcphy_hd *hd1; modplcphy_hd *hd2; unsigned char *frame1; unsigned char *frame2;

/* Puerto serie utilizado. */ /* Puerto serie utilizado. */ /* Indicador de trama corrompida. */ /* Contador. */ /* Tamao de trama enviada/recibida. */ /* Tamao de trama. */ /* Contador de ciclos de prueba. */ /* Distancia. */ /* Cantidad de tramas de prueba. */ /* Cantidad de bits errados. */ /* Cantidad de bits perdidos. */ /* Cantidad de bits enviados. */ /* Cantidad de tramas corrompidas. */ /* Cantidad de tramas prdidas. */ /* Diferencia de tiempo. */ /* Tiempo inicial. */ /* Tiempo final. */ /* Diferencia entre bytes. */ /* Manejador de interfaz con la capa fsica del modem PLC. */ /* Manejador de interfaz con la capa fsica del modem PLC. */ /* Trama de prueba, */ /* Trama de prueba. */

/* Carga parmetros. */ if (argc < 4) return -1; port1 = atoi(argv[1]);

788

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


port2 = atoi(argv[2]); frames = atoi(argv[3]); /* Prueba. */ while(1) { /* Inicializa conexiones con capa fsica. */ hd1 = modplcphy_init(port1); if (!hd1) break; hd2 = modplcphy_init(port2); if (!hd2) break; /* Obtiene el tamao mximo de trama. */ framesize = modplcphy_getpayloadsize(hd1, 0); if (framesize > modplcphy_getpayloadsize(hd2, 0)) framesize = modplcphy_getpayloadsize(hd2, 0); /* Reserva memoria para almacenar las tramas de prueba. */ frame1 = (unsigned char *) malloc(sizeof(unsigned char) * framesize); if (!frame1) break; frame2 = (unsigned char *) malloc(sizeof(unsigned char) * framesize); if (!frame2) break; /* Inicializa contadores. */ badbits = 0; lostbits = 0; sentbits = 0; badframes = 0; lostframes = 0; /* Inicia la secuencia pseudoaleatoria. */ srand((unsigned) time(NULL)); /* Prueba de envo y recepcin de tramas. */ for(c = 1; c <= frames; c++) { /* Genera trama de prueba. */ printf("ciclo %li - ", c); size = (rand() % framesize) + 1; switch(rand() % 14) { /* Patrn 00000000. */ case 0: printf("patrn 00000000 - "); for(i = 0; i < size; i++) frame1[i] = 0x00; break; /* Patrn 11111111. */ case 1: printf("patrn 11111111 - "); for(i = 0; i < size; i++) frame1[i] = 0xff; break; /* Patrn 01010101. */ case 2: printf("patrn 01010101 - "); for(i = 0; i < size; i++) frame1[i] = 0x55; break; /* Patrn 10101010. */ case 3: printf("patrn 10101010 - "); for(i = 0; i < size; i++) frame1[i] = 0xaa; break;

FernandoArielBeunza79156

789

Tesis de Grado en Ingeniera Informtica


/* Patrn 00110011. */ case 4: printf("patrn 00110011 - "); for(i = 0; i < size; i++) frame1[i] = 0x33; break; /* Patrn 11001100. */ case 5: printf("patrn 11001100 - "); for(i = 0; i < size; i++) frame1[i] = 0xcc; break; /* Patrn 01100110. */ case 6: printf("patrn 01100110 - "); for(i = 0; i < size; i++) frame1[i] = 0x66; break; /* Patrn 10011001. */ case 7: printf("patrn 10011001 - "); for(i = 0; i < size; i++) frame1[i] = 0x99; break; /* Patrn 00001111. */ case 8: printf("patrn 00001111 - "); for(i = 0; i < size; i++) frame1[i] = 0x0f; break; /* Patrn 11110000. */ case 9: printf("patrn 11110000 - "); for(i = 0; i < size; i++) frame1[i] = 0xf0; break; /* Patrn 00111100. */ case 10: printf("patrn 00111100 - "); for(i = 0; i < size; i++) frame1[i] = 0x3c; break; /* Patrn 11000011. */ case 11: printf("patrn 11000011 - "); for(i = 0; i < size; i++) frame1[i] = 0xc3; break; /* Patrn secuencia. */ case 12: printf("patrn secuencia - "); for(i = 0; i < size; i++) frame1[i] = (char) (i & 0x00ff); break; /* Patrn aleatorio. */ case 13: printf("patrn aleatorio - "); for(i = 0; i < size; i++) frame1[i] = (char) ((rand() % 256) & 0x00ff);

790

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


break; } /* Limpia el buffer del receptor. */ modplcphy_clrbuffer(hd2, 0); /* Establece el modo captura para el receptor. */ modplcphy_capframe(hd2, 0, size); /* Enva trama de prueba. */ gettimeofday(&time1, NULL); size = modplcphy_sndframe(hd1, 0, frame1, size); if (!size) { badframes ++; continue; } sentbits += (size * 8); /* Recibe trama de prueba. */ if (!modplcphy_poll(hd2, 0)) { printf("%li bits - trama perdida\r\n", size * 8); lostbits += (size * 8); lostframes ++; continue; } size = modplcphy_getframe(hd2, 0, frame2, size); gettimeofday(&time2, NULL); /* Calcula el tiempo entre envo y recepcin. */ difftime = ((double) (time2.tv_sec - time1.tv_sec) * 1000 + (double) (time2.tv_usec - time1.tv_usec) / 1000.0) + 0.5; printf("%li bits - %.1f milisegundos\r\n", size * 8, difftime); /* Cuenta los errores ocurridos. */ badframe = 0; for(i = 0; i < size; i++) { dist = badbits; diff = frame1[i] ^ frame2[i]; if (diff & 0x80) badbits ++; if (diff & 0x40) badbits ++; if (diff & 0x20) badbits ++; if (diff & 0x10) badbits ++; if (diff & 0x08) badbits ++; if (diff & 0x04) badbits ++; if (diff & 0x02) badbits ++; if (diff & 0x01) badbits ++; dist = badbits - dist; if (!dist) continue; badframe = 1; } if (badframe) badframes ++; } /* Imprime resultados de la prueba. */ printf("\r\n"); printf("Bits enviados: %li\r\n", sentbits); printf("Bits perdidos: %li (%.3f%%)\r\n", lostbits, ((double) lostbits / (double) sentbits) * 100); printf("Bits errados: %li (%.3f%%)\r\n", badbits, ((double) badbits / (double) sentbits) * 100); printf("Tramas enviadas: %li\r\n", frames); printf("Tramas prdidas: %li (%.3f%%)\r\n",

FernandoArielBeunza79156

791

Tesis de Grado en Ingeniera Informtica


lostframes, ((double) lostframes / (double) frames) * 100); printf("Tramas corrompidas: %li (%.3f%%)\r\n", badframes, ((double) badframes / (double) frames) * 100); printf("\r\n"); break; } /* Libera memoria reservada para almacenar tramas de prueba. */ if (frame2) free(frame2); if (frame1) free(frame1); /* Finaliza las conexiones. */ modplcphy_release(hd2); modplcphy_release(hd1); /* Fin. */ return 0; }

G.4.2.2. Archivo testap.c


/* testap.c: Pruebas de funcionamiento de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include <stdio.h> #include <stdlib.h> #include "../../../modem_driver/linux/modplcap/modplcap.h"

/* Funcin main. */ int main(int argc, char *argv[]) { /* Variables. */ int port; unsigned char count; unsigned char status; modplcap_ftype type; modplcap_msg msg; modplcap_hd *hd;

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

Puerto serie utilizado. */ Multiplicidad. */ Estado de los faros. */ Tipo de campo. */ Mensaje. */ Manejador de interfaz con la capa de aplicacin del modem PLC. */

/* Carga parmetros. */ if (argc < 2) return -1; port = atoi(argv[1]); /* Prueba. */ while(1) { /* Inicializa la conexin con capa de aplicacin. */ hd = modplcap_init(port); if (!hd) break; /* Suscripcin a grupos de difusin. */ if (!modplcap_publish(hd, 1)) break; if (!modplcap_subscribe(hd, 2)) break; /* Verifica el estado de los focos. */ printf("Verificacin de estado de focos\r\n\n");

792

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


modplcap_newmsg(hd, &msg, 1, 0x8000); modplcap_sendmsg(&msg); modplcap_destroymsg(&msg); if (!modplcap_receivemsg(hd, &msg)) break; modplcap_getfield(&msg, &type, &count, &status); modplcap_destroymsg(&msg); printf("* Estado luz de posicin : "); if (status & 0x01) printf("OK\r\n"); else printf("Falla\r\n"); printf("* Estado luz de baja : "); if (status & 0x02) printf("OK\r\n"); else printf("Falla\r\n"); printf("* Estado luz de alta : "); if (status & 0x04) printf("OK\r\n"); else printf("Falla\r\n"); printf("* Estado luz de guio : "); if (status & 0x08) printf("OK\r\n"); else printf("Falla\r\n"); /* Encendido de luz de guio derecho. */ printf("\r\nEncendido de luz de guio derecho "); printf("(presione una tecla para continuar)\r\n\n"); getc(stdin); modplcap_newmsg(hd, &msg, 1, 0x8001); status = 0x01; modplcap_putfield(&msg, MODPLCAP_UINT8TYPE, 1, &status); modplcap_sendmsg(&msg); modplcap_destroymsg(&msg); /* Apagado de luz de guio derecho. */ printf("Apagado de luz de guio derecho "); printf("(presione una tecla para continuar)\r\n\n"); getc(stdin); modplcap_newmsg(hd, &msg, 1, 0x8001); status = 0x00; modplcap_putfield(&msg, MODPLCAP_UINT8TYPE, 1, &status); modplcap_sendmsg(&msg); modplcap_destroymsg(&msg); /* Encendido de luz de guio izquierdo. */ printf("Encendido de luz de guio izquierdo "); printf("(presione una tecla para continuar)\r\n\n"); getc(stdin); modplcap_newmsg(hd, &msg, 1, 0x8002); status = 0x01; modplcap_putfield(&msg, MODPLCAP_UINT8TYPE, 1, &status); modplcap_sendmsg(&msg); modplcap_destroymsg(&msg); /* Apagado de luz de guio izquierdo. */ printf("Apagado de luz de guio izquierdo "); printf("(presione una tecla para continuar)\r\n\n"); getc(stdin); modplcap_newmsg(hd, &msg, 1, 0x8002); status = 0x00; modplcap_putfield(&msg, MODPLCAP_UINT8TYPE, 1, &status); modplcap_sendmsg(&msg); modplcap_destroymsg(&msg); /* Encendido de luces de posicin. */ printf("Encendido de luces de posicin "); printf("(presione una tecla para continuar)\r\n\n"); getc(stdin);

FernandoArielBeunza79156

793

Tesis de Grado en Ingeniera Informtica


modplcap_newmsg(hd, &msg, 1, 0x8003); status = 0x01; modplcap_putfield(&msg, MODPLCAP_UINT8TYPE, 1, &status); modplcap_sendmsg(&msg); modplcap_destroymsg(&msg); /* Encendido de luces bajas. */ printf("Encendido de luces bajas "); printf("(presione una tecla para continuar)\r\n\n"); getc(stdin); modplcap_newmsg(hd, &msg, 1, 0x8003); status = 0x02; modplcap_putfield(&msg, MODPLCAP_UINT8TYPE, 1, &status); modplcap_sendmsg(&msg); modplcap_destroymsg(&msg); /* Encendido de luces altas. */ printf("Encendido de luces altas "); printf("(presione una tecla para continuar)\r\n\n"); getc(stdin); modplcap_newmsg(hd, &msg, 1, 0x8003); status = 0x03; modplcap_putfield(&msg, MODPLCAP_UINT8TYPE, 1, &status); modplcap_sendmsg(&msg); modplcap_destroymsg(&msg); /* Apagado de luces de iluminacin. */ printf("Apagado de luz luces de iluminacin "); printf("(presione una tecla para continuar)\r\n\n"); getc(stdin); modplcap_newmsg(hd, &msg, 1, 0x8003); status = 0x00; modplcap_putfield(&msg, MODPLCAP_UINT8TYPE, 1, &status); modplcap_sendmsg(&msg); modplcap_destroymsg(&msg); break; } /* Finaliza la conexin. */ modplcap_release(hd); /* Fin. */ return 0; }

G.4.2.3. Archivo testapcpp.cpp


/* testapcpp.c: Pruebas de funcionamiento de la capa de aplicacin del modem PLC. */

/* Archivos includos necesarios. */ #include <iostream> #include <stdlib.h> #include "../../../modem_driver/linux/modplcapcpp/modplcapcpp.h"

using namespace std;

/* Funcin main. */ int main(int argc, char *argv[]) { /* Variables. */

794

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


int port; unsigned char count; unsigned char status; modplcapcpp_ftype type; modplcapcpp_msg *msg; modplcapcpp *hd; /* /* /* /* /* /* Puerto serie utilizado. */ Multiplicidad. */ Estado de los faros. */ Tipo de campo. */ Mensaje. */ Manejador de interfaz con la capa de aplicacin del modem PLC. */

/* Carga parmetros. */ if (argc < 2) return -1; port = atoi(argv[1]); /* Prueba. */ while(1) { /* Inicializa la conexin con capa de aplicacin. */ hd = new modplcapcpp(port); if (!hd) break; /* Suscripcin a grupos de difusin. */ if (!hd->publish(1)) break; if (!hd->subscribe(2)) break; /* Verifica el estado de los focos. */ cout << "Verificacin de estado de focos" << endl << endl; msg = new modplcapcpp_msg(hd, 1, 0x8000); if (!msg) break; msg->sendmsg(); delete msg; msg = new modplcapcpp_msg(hd); if (!msg) break; msg->getfield(&type, &count, &status); delete msg; cout << "* Estado luz de posicin : "; if (status & 0x01) cout << "OK" << endl; else cout << "Falla" << endl; cout << "* Estado luz de baja : "; if (status & 0x02) cout << "OK" << endl; else cout << "Falla" << endl; cout << "* Estado luz de alta : "; if (status & 0x04) cout << "OK" << endl; else cout << "Falla" << endl; cout << "* Estado luz de guio : "; if (status & 0x08) cout << "OK" << endl; else cout << "Falla" << endl; /* Encendido de luz de guio derecho. */ cout << endl << "Encendido de luz de guio derecho "; cout << "(presione una tecla para continuar)" << endl << endl; cin.get(); msg = new modplcapcpp_msg(hd, 1, 0x8001); if (!msg) break; status = 0x01; msg->putfield(MODPLCAPCPP_UINT8TYPE, 1, &status); msg->sendmsg(); delete msg; /* Apagado de luz de guio derecho. */ cout << "Apagado de luz de guio derecho "; cout << "(presione una tecla para continuar)" << endl << endl; cin.get();

FernandoArielBeunza79156

795

Tesis de Grado en Ingeniera Informtica


msg = new modplcapcpp_msg(hd, 1, 0x8001); if (!msg) break; status = 0x00; msg->putfield(MODPLCAPCPP_UINT8TYPE, 1, &status); msg->sendmsg(); delete msg; /* Encendido de luz de guio izquierdo. */ cout << "Encendido de luz de guio izquierdo "; cout << "(presione una tecla para continuar)" << endl << endl; cin.get(); msg = new modplcapcpp_msg(hd, 1, 0x8002); if (!msg) break; status = 0x01; msg->putfield(MODPLCAPCPP_UINT8TYPE, 1, &status); msg->sendmsg(); delete msg;; /* Apagado de luz de guio izquierdo. */ cout << "Apagado de luz de guio izquierdo "; cout << "(presione una tecla para continuar)" << endl << endl; cin.get(); msg = new modplcapcpp_msg(hd, 1, 0x8002); if (!msg) break; status = 0x00; msg->putfield(MODPLCAPCPP_UINT8TYPE, 1, &status); msg->sendmsg(); delete msg; /* Encendido de luces de posicin. */ cout << "Encendido de luces de posicin "; cout << "(presione una tecla para continuar)" << endl << endl; cin.get(); msg = new modplcapcpp_msg(hd, 1, 0x8003); if (!msg) break; status = 0x01; msg->putfield(MODPLCAPCPP_UINT8TYPE, 1, &status); msg->sendmsg(); delete msg; /* Encendido de luces bajas. */ cout << "Encendido de luces bajas "; cout << "(presione una tecla para continuar)" << endl << endl; cin.get(); msg = new modplcapcpp_msg(hd, 1, 0x8003); if (!msg) break; status = 0x02; msg->putfield(MODPLCAPCPP_UINT8TYPE, 1, &status); msg->sendmsg(); delete msg; /* Encendido de luces altas. */ cout << "Encendido de luces altas "; cout << "(presione una tecla para continuar)" << endl << endl; cin.get(); msg = new modplcapcpp_msg(hd, 1, 0x8003); if (!msg) break; status = 0x03; msg->putfield(MODPLCAPCPP_UINT8TYPE, 1, &status); msg->sendmsg(); delete msg; /* Apagado de luces de iluminacin. */ cout << "Apagado de luz luces de iluminacin "; cout << "(presione una tecla para continuar)" << endl << endl; cin.get(); msg = new modplcapcpp_msg(hd, 1, 0x8003); if (!msg) break; status = 0x00; msg->putfield(MODPLCAPCPP_UINT8TYPE, 1, &status); msg->sendmsg();

796

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica


delete msg; break; } /* Finaliza la conexin. */ delete hd; /* Fin. */ return 0; }

FernandoArielBeunza79156

797

Tesis de Grado en Ingeniera Informtica

798

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica

Glosario
ACKN Acknowledgement Conjunto de bits utilizado en las tramas CAN para indicar si la trama fue recibida correctamente por los destinatarios de la misma. Analogic to Digital Converter Dispositivo electrnico que permite convertir una seal analgica en un valor cuantificable capaz de ser representado por medio de una seal digital. Application Protocol Data Unit Unidad de datos definida por el protocolo de capa de aplicacin del estndar CEBus. Advanced RISC Machines Familia de microcontroladores RISC desarrollados originalmente por la empresa Acorn Computers Ltd. En la actualidad empresas como Freescale, Texas Instrument, Atmel, entre otras; implementan microcontroladores de sta familia. Advanced RISC Machines 9 Modelo de microcontrolador perteneciente a la familia ARM, que puede procesar alrededor de 220 millones de instrucciones por segundo con una frecuencia de reloj de 200 MHz. Address Resolution Protocol. Protocolo que permite relacionar direcciones lgicas con direcciones fsicas propias de un dispositivo. Automatic Repeat Request. Protocolo de comunicacin que permite la retransmisin de informacin en caso de no recibir confirmacin de recepcin por parte del destinatario. Amplitude Shift Keying Tcnica de modulacin que utiliza la amplitud de una portadora para codificar la informacin binaria a enviar. Advanced Virtual RISC Familia de microcontroladores RISC desarrollados por la empresa Atmel. Binary Frecuency Shift Keying Tcnica de modulacin que utiliza la frecuencia de una portadora para codificar la informacin binaria a enviar.

ADC

APDU

ARM

ARM9

ARP

ARQ

ASK

AVR

BFSK

FernandoArielBeunza79156

799

Tesis de Grado en Ingeniera Informtica BPL Broadband over Power Lines Servicio de banda ancha sobre lneas elctricas. Binary Phase Shift Keying. Tcnica de modulacin que utiliza la fase de una portadora para codificar la informacin binaria a enviar. En este caso se emplean 2 fases que permiten codificar un bit de informacin por smbolo. CEBus Application Language Lenguaje definido por el estndar CEBus, para garantizar la interoperabilidad entre los distintos tipos de dispositivos que cumplan con ste estndar. Controller Area Network Red de datos utilizada en aplicaciones de control. Consumer Electronics Bus Estndar desarrollado para el mbito del control domtico.

BPSK

CAL

CAN

CEBus

CENELEC Comit Europen de Normalisation Electrotechnique Es el Comit Europeo de Normalizacin Electrotcnica. Chirp Chirp Seal conformada por un barrido en frecuencia dentro de un determinado rango de una seal senoidal. Control Network Protocol Protocolo de control de red basado en el modelo OSI. Cyclic Redundancy Code Cdigo calculado a partir de una trama de datos utilizado para verificar que dicha trama no se haya corrompido en el momento de la transmisin. Carrier Sense Multiple Access Protocolo encargado de controlar el acceso a un nico medio de comunicacin compartido por varios dispositivos, basado en el sensado del medio previo a realizar una transmisin.

CNP

CRC

CSMA

CSMA/CA Carrier Sense Multiple Access with Collision Avoidance Protocolo encargado de controlar el acceso a un nico medio de comunicacin compartido por varios dispositivos, basado en el sensado del medio previo a realizar una transmisin. sta versin particular del protocolo implementa un mecanismo que evita las colisiones de paquetes de informacin transmitidos en forma simultnea.

800

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica CSMA/CD Carrier Sense Multiple Access with Collision Detection Protocolo encargado de controlar el acceso a un nico medio de comunicacin compartido por varios dispositivos, basado en el sensado del medio previo a realizar una transmisin. sta versin particular del protocolo implementa un mecanismo de deteccin de las colisiones de paquetes de informacin que ocurren cuando varios dispositivos inician la transmisin en forma simultnea. CSMA/CR Carrier Sense Multiple Access with Collision Resolution Protocolo encargado de controlar el acceso a un nico medio de comunicacin compartido por varios dispositivos, basado en el sensado del medio previo a realizar una transmisin. sta versin particular del protocolo implementa un mecanismo de deteccin y resolucin de las colisiones de paquetes de informacin que ocurren cuando varios dispositivos inician la transmisin en forma simultnea. CTL ConTroL Word Campo de control de un paquete de UPB utilizado para especificar informacin de control acerca del paquete (tamao del paquete, etc.). Domestic Digital Bus Red de fibra ptica con topologa anillo utilizada para interconectar distintos dispositivos de automvil Digital to Analogic Converter Dispositivo electrnico que permite convertir un valor cuantificable representado por medio de una seal digital en una seal analgica. Differential Binary Phase Shift Keying Tcnica de modulacin que utiliza la fase de una portadora para codificar la informacin binaria a enviar. En este caso se emplean 2 fases que permiten codificar un bit de informacin por smbolo. A diferencia de BPSK, sta tcnica no requiere de un recuperador de portadora. DC-BUS Red de datos desarrollada por la empresa Yamar Electronics Ltd. que emplea como medio fsico la red elctrica del automvil Discrete Fourier Transform Extensin de la transformada de Fourier a aplicaciones discretas utilizada en el demodulador OFDM para recuperar la informacin enviada. Destination ID Campo de un paquete UPB utilizado para especificar al dispositivo destinatario.

D2B

DAC

DBPSK

DC-BUS

DFT

DID

FernandoArielBeunza79156

801

Tesis de Grado en Ingeniera Informtica DLC Data Length Code Campo de una trama CAN utilizado para especificar el tamao de la misma. Differential Quadrature Phase Shift Keying Tcnica de modulacin que utiliza la fase de una portadora para codificar la informacin binaria a enviar. En este caso se emplean cuatro fases que permiten codificar dos bits de informacin por smbolo. A diferencia de QPSK, sta tcnica no requiere de un recuperador de portadora. Direct Sequence Spread Spectrum Tcnica de expansin del espectro basada en la utilizacin de un cdigo pseudoaleatorio para enviar la informacin. Electrically Erasable Programmable Read Only Tipo de memoria ROM que permite el borrado y programacin de su contenido elctricamente. Es utilizada en bancos de memoria cuando se desarrolla firmware que debe ser modificado reiteradas veces. Tambin puede ser empleada para almacenar datos que requieren persistir (lo que no permite una memoria tipo RAM). End Of Frame Conjunto de bits utilizado en las tramas CAN y J1850 para indicar el final de la misma. Foward Error Correction Es un mecanismo de correccin de errores que permite corregir errores en el receptor sin necesidad de retransmisin. Field Programmable Gate Array Dispositivo compuesto por bloques de lgica programables. Frecuency Shift Keying Tcnica de modulacin que utiliza la frecuencia de una portadora para codificar la informacin binaria a enviar. Home Area Network Es un tipo de red destinada a interconectar los distintos dispositivos que se puede encontrar en un hogar. High Frecuency Banda del espectro de frecuencias utilizada para las comunicaciones PLC comprendida entre 1 y 30 MHz.

DQPSK

DSSS

EEPROM

EOF

FEC

FPGA

FSK

HAN

HF

802

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica IDE IDentifier Extension Bit utilizado en las tramas extendidas de CAN parte B, para diferenciarlas de las tramas estndar. Inverse Discrete Fourier Transform Extensin de la inversa de la transformada de Fourier a aplicaciones discretas utilizada en el modulador OFDM para generar el smbolo asociado a la informacin a enviar. In Frame Response Bit utilizado en las tramas J1850 para indicar que el destinatario de la misma puede emitir una trama de respuesta a continuacin de la primera. Internet Protocol Protocolo de comunicaciones entre redes que forma parte de la capa de red del modelo OSI, encargado de la identificacin de nodos y del encaminado de paquetes de informacin. International Organization for Standardization Es un organismo que se encarga de promover el desarrollo de normas internacionales de fabricacin, comercio y comunicacin para todas las ramas industriales, salvo la elctrica y la electrnica. SAE J1850 Bus Red de datos utilizada para intercambio de informacin entre dispositivos de un automvil. Local Interconnect Network Red de datos utilizada como subred de CAN en aplicaciones automotrices. Logical Link Control Protocolo de control de lgica de enlace que forma parte de la capa de enlace del modelo OSI, encargado de establecer un canal de comunicaciones sin errores y con control de flujo de la informacin entre el transmisor y el receptor. Local Operating Network Es un tipo de red utilizada en la automatizacin de edificios que permite la interconexin de sensores, actuadores y otros tipos de dispositivos inteligentes.

IDFT

IFR

IP

ISO

J1850

LIN

LLC

LON

LonWorks Local Operating Network Works Estandar utilizado en dispositivos destinados a la automatizacin de edificios basado en el protocolo CNP.

FernandoArielBeunza79156

803

Tesis de Grado en Ingeniera Informtica LPDU Link Protocol Data Unit Unidad de datos definida por el protocolo de capa de enlace del estndar CEBus. Medium Access Control Protocolo de control de acceso al medio que forma parte de la capa de enlace del modelo OSI, encargado de gestionar el uso compartido de un nico medio de comunicacin utilizado por varios dispositivos. Message Data Arguments Campo de un paquete UPB reservado para enviar los parmetros asociados a un comando. Message Data ID Campo de un paquete UPB reservado para especificar el comando, o la respuesta a ste. Media Oriented System Transport Red multimedia de alta velocidad optimizada para la industria del automvil.

MAC

MDA

MDID

MOST

Neuron ID Neuron Identifier Identificador utilizado en los dispositivos que cumplen con el estndar LonWorks. Dicho identificador es nico para cada dispositivo y es establecido por el fabricante del mismo en el momento de fabricacin. NID Network ID Campo de un paquete UPB utilizado para especificar la red en donde se encuentra el dispositivo destinatario. Network Protocol Data Unit Unidad de datos definida por el protocolo de capa de red del estndar CEBus. Non Return to Zero Mecanismo de codificacin de tramas en donde no se retorna a valor 0 entre bits consecutivos de valor 1. Network Idle Time Segmento de tiempo al final del ciclo de comunicacin recurrente de FlexRay que se deja sin utilizar como separacin entre ciclos de comunicacin. Orthogonal Frecuency Division Multiplex Mecanismo de multiplexacin por divisin de frecuencias ortogonales.

NPDU

NRZ

NT

OFDM

804

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica OSEK Offene Systeme und deren Schnittstellen fr die Elektronik in Kraftfahrzeugen Es un estndar abierto sobre interfaces para la electrnica de automviles. Consiste en un sistema operativo integrado por una pila de protocolos de comunicacin y administracin de redes orientado a aplicaciones empotradas utilizadas en automviles. Open Sytem Interconnection Es un modelo de red propuesto por ISO utilizado como marco de referencia para la definicin de arquitecturas de interconexin de sistemas de comunicaciones. Peak to Average Power Ratio Parmetro utilizado para medir el margen de amplitud de una seal. Power Line Communication Sistema de comunicacin que utiliza las redes de alimentacin como medio fsico de transmisin de informacin. Pulse Position Modulation Tcnica de modulacin que se utiliza la posicin de un pulso para codificar la informacin a enviar. Pulse Width Modulation Tcnica de modulacin que utiliza el ancho de pulso para codificar la informacin a enviar. Phase Shift Keying Tcnica de modulacin que utiliza la fase de una portadora para codificar la informacin a enviar. Quadrature Amplitude Modulation Tcnica de modulacin de amplitud en cuadratura. Es una variante de la modulacin en amplitud ms eficiente que ASK, ya que la informacin se codifica por medio de la amplitud y fase de la portadora permitiendo transmitir ms bits por smbolo. Quadrature Phase Shift Keying Tcnica de modulacin que utiliza la fase de una portadora para codificar la informacin binaria a enviar. En este caso se emplean 4 fases que permiten codificar 2 bits de informacin por smbolo. Random Access Memory Tipo de memoria voltil de acceso aleatorio utilizada en bancos de memoria que permite operaciones de lectura y escritura. Es empleada para el almacenamiento de datos transitorios.

OSI

PAR

PLC

PPM

PWM

PSK

QAM

QPSK

RAM

FernandoArielBeunza79156

805

Tesis de Grado en Ingeniera Informtica RISC Reduced Instruction Set Computer Es un tipo de microprocesador que se caracteriza por ofrecer un conjunto de instrucciones de tamao fijo que puede manipular un limitado conjunto de tipos de datos, y solamente dispone de dos instrucciones para acceder a la memoria de datos. La ventaja que brinda este tipo de microprocesador es que las instrucciones se ejecutan empleando muy pocos ciclos de reloj, permitiendo mayores velocidades de procesamiento. ROBust OFDM Es mecanismo para enviar informacin repetida por medio de la tcnica OFDM, para aumentar la confiabilidad a costas de una reduccin en la velocidad de transferencia. Read Only Memory Tipo de memoria no voltil de acceso aleatorio utilizada en bancos de memoria que solamente permite operaciones de lectura. Es empleada para el almacenamiento de firmware de microcontroladores. Recommended Standard 232 Interfaz utilizada para el intercambio de datos en forma serial entre un equipo terminal de datos (por ejemplo, una PC) y un equipo de comunicacin de datos (por ejemplo, un modem). Remote Transmission Request Bit de una trama CAN utilizado para indicar que la misma es una trama de datos. Society of Automotive Engineers Es la Sociedad de Ingenieros de Automocin cuya funcin es definir estndares para todo tipo de vehculos (automviles, aviones, barcos, etc.). Source ID Campo de un paquete UPB utilizado para especificar al dispositivo que dio origen al paquete. Start Of Frame Bit utilizado en las tramas CAN y J1850 para indicar el comienzo de la misma. Substitute Remote Request Bit utilizado en las tramas extendidas de CAN parte B, ubicado en la misma posicin donde se encuentra el bit RTR de una trama estndar. Su existencia se debe a razones de compatibilidad entre las tramas estndar y las tramas extendidas. Symbol Window Segmento opcional de tiempo del ciclo de comunicacin recurrente de FlexRay utilizado para evaluar el estado del medio.

ROBO

ROM

RS232

RTR

SAE

SID

SOF

SRR

SW

806

FernandoArielBeunza79156

Tesis de Grado en Ingeniera Informtica TCC Turbo Convolutional Code Tipo de cdigo de correccin de errores que permite comunicaciones confiables y su eficiencia energtica est muy cerca del lmite terico de Shannon. Time Division Multiplexing Es una tcnica de multiplexacin en donde se asigna todo el ancho de banda de un medio de transmisin a cada canal durante un intervalo de tiempo. Time Division Multiple Access Es una tcnica de multiplexacin que distribuye la informacin en ranuras de tiempo de forma alternada, brindando acceso mltiple sobre un nmero reducido de frecuencias. Transport Control Protocol Protocolo de control de transporte de informacin entre dos nodos que forma parte de la capa de transporte del modelo OSI, encargado de establecer un canal de comunicaciones confiable entre dos nodos. Transistor Transistor Logic Tecnologa de construccin de circuitos electrnicos digitales basada en transistores bipolares, que se caracteriza por trabajar con dos rangos de tensin especficos para representar el cero y uno lgicos. Universal Asynchronous Receiver Transmitter Dispositivo utilizado para el intercambio de datos en forma serial entre dispositivos. Universal Power Bus Es un estndar de comunicaciones para dispositivos usados en la automatizacin del hogar. Universal Serial Bus Interfaz utilizada para el intercambio de datos en forma serial entre una PC y diversos perifricos (por ejemplo, teclados, impresoras, etc.). Vehicle Distributes eXecutive Sistema operativo integrado por una pila de protocolos de comunicacin y administracin de redes orientado a aplicaciones empotradas en automviles, similar a OSEK. Variable Pulse Width Tcnica que emplea el ancho de pulso para codificar la informacin a enviar.

TDM

TDMA

TCP

TTL

UART

UPB

USB

VDX

VPW

FernandoArielBeunza79156

807

Tesis de Grado en Ingeniera Informtica VSB-SC Vestigial Sideband Suppressed Carrier Tipo de modulacin de amplitud que utiliza para transmitir la informacin, una de las banda laterales y un vestigio de la otra, suprimiendo la portadora para ahorrar energa. Wide Area Network Es un tipo de red que permite interconectar computadoras en un rango de distancias comprendido entre los 100 y 1000 kilmetros. Wireless Fidelity Es un tipo de red que permite interconectar computadoras de forma inalmbrica. X10 Es un estndar de comunicaciones para el control remoto de dispositivos elctricos.

WAN

WiFi

X10

808

FernandoArielBeunza79156

You might also like