Professional Documents
Culture Documents
FACULTAD DE INGENIERA
Diseo de un Sistema de Intercambio de Informacin para Dispositivos Intercomunicados por Redes PLC de Automviles
SEPTIEMBRE 2011
Diseo de un Sistema de Intercambio de Informacin para Dispositivos Intercomunicados por Redes PLC de Automviles
SEPTIEMBRE 2011
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
FernandoArielBeunza79156
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
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
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.
FernandoArielBeunza79156
17
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.
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.
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.
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).
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).
FernandoArielBeunza79156
19
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
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.
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.
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.
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.
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.
Para acceder a las variables de instancia de cada objeto, CAL define un conjunto de mtodos enumerados en la tabla 2.4.
FernandoArielBeunza79156
23
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
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>]
D D
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
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
140 KHz 148.5 KHz Disponible para los consumidores sin restricciones.
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
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.
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
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.
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
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.
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
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
Por ltimo, UPB define una serie de respuestas a comandos que se detallan en la tabla 2.9.
30
FernandoArielBeunza79156
Respuesta
MDID (Hex) 90 91 92 93 AF
Setup Time Device State Device Status Signal Strength Noise Level
94 - AE Unused
8B - 8F Unused
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.
FernandoArielBeunza79156
31
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
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.
Aplicacin Compatibilidad
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
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
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.
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.
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.
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
Un datagrama se encuentra conformado de los siguientes campos: versin, formato de paquete, formato de direccin, tamao del dominio, direccin, dominio y el paquete.
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.
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.
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.
36
FernandoArielBeunza79156
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.
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.
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.
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
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.
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
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.
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.
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.
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.
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
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.
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.
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
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.
46
FernandoArielBeunza79156
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.
FernandoArielBeunza79156
47
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.
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
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.
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.
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).
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
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.
52
FernandoArielBeunza79156
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
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
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.
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
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.
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.
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.
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).
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].
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.
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
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.
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.
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
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.
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.
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.
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.
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.
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
66
FernandoArielBeunza79156
Encabezado 12 bytes
CRC
Datos
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.
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.
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).
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.
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).
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.
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
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.
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.
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.
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.
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.
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.
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.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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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.
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.
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.
FernandoArielBeunza79156
83
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.
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 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.
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.
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.
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.
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.
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
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
FernandoArielBeunza79156
91
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.
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.
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.
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
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.
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
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.
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
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
98
FernandoArielBeunza79156
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.
100
FernandoArielBeunza79156
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
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.
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.
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
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.
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).
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.
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
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).
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
16 bits 2 bytes
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).
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.
FernandoArielBeunza79156
113
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.
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.
116
FernandoArielBeunza79156
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).
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).
FernandoArielBeunza79156
119
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.
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.
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
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.
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.
124
FernandoArielBeunza79156
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.
FernandoArielBeunza79156
125
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
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.
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.
128
FernandoArielBeunza79156
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.
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
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
Datos (capacidad mxima de capa de red - 16) bits (capacidad mxima de capa de red - 2) bytes
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.
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.
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).
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
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.
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.
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
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.
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 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.
140
FernandoArielBeunza79156
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.
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.
FernandoArielBeunza79156
143
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).
FernandoArielBeunza79156
145
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
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.
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.
150
FernandoArielBeunza79156
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
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
FernandoArielBeunza79156
153
154
FernandoArielBeunza79156
FernandoArielBeunza79156
155
156
FernandoArielBeunza79156
FernandoArielBeunza79156
157
158
FernandoArielBeunza79156
FernandoArielBeunza79156
159
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).
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
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:
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
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.
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
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.
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
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
166
FernandoArielBeunza79156
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.
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).
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.
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
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
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
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%
Bits perdidos
Bits errneos
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%
Tramas errneas
0 5 10 15 20 25 30 35
Tramas perdidas
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
25,000% 20,000%
Bits errneos
Bits perdidos
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.
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
35,000% 30,000%
50,000% 45,000%
Tramas perdidas
Tramas erroneas
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.
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).
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).
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.
FernandoArielBeunza79156
181
182
FernandoArielBeunza79156
FernandoArielBeunza79156
183
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.
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.
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
188
FernandoArielBeunza79156
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.
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
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
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
198
FernandoArielBeunza79156
Los mdulos constituyentes del modem PLC prototipo (figura A1), se describe a continuacin:
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
FernandoArielBeunza79156
201
202
FernandoArielBeunza79156
FernandoArielBeunza79156
203
204
FernandoArielBeunza79156
FernandoArielBeunza79156
205
206
FernandoArielBeunza79156
FernandoArielBeunza79156
207
208
FernandoArielBeunza79156
FernandoArielBeunza79156
209
210
FernandoArielBeunza79156
FernandoArielBeunza79156
211
212
FernandoArielBeunza79156
FernandoArielBeunza79156
213
214
FernandoArielBeunza79156
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
216
FernandoArielBeunza79156
FernandoArielBeunza79156
217
218
FernandoArielBeunza79156
FernandoArielBeunza79156
219
220
FernandoArielBeunza79156
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
FernandoArielBeunza79156
223
224
FernandoArielBeunza79156
FernandoArielBeunza79156
225
226
FernandoArielBeunza79156
FernandoArielBeunza79156
227
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
FernandoArielBeunza79156
229
230
FernandoArielBeunza79156
FernandoArielBeunza79156
231
232
FernandoArielBeunza79156
FernandoArielBeunza79156
233
234
FernandoArielBeunza79156
FernandoArielBeunza79156
235
236
FernandoArielBeunza79156
FernandoArielBeunza79156
237
238
FernandoArielBeunza79156
FernandoArielBeunza79156
239
Capa de aplicacin
(varia segn plataforma)
Capa de presentacin
(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 fsica (mdulo de procesamiento de seales)
phy.h phy.c main.c
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
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
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
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.
/* 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' '$'
/* 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
#endif
242
FernandoArielBeunza79156
/* 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
/* 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;
/* 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. */
FernandoArielBeunza79156
243
/* 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
/* 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
FernandoArielBeunza79156
245
246
FernandoArielBeunza79156
#endif
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif
/* 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); }
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif
248
FernandoArielBeunza79156
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif
/* 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); }
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif
250
FernandoArielBeunza79156
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif
/* 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); }
252
FernandoArielBeunza79156
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif
/* 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)); }
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif
/* 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
/* 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; }
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif
/* 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)); }
FernandoArielBeunza79156
255
/* 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; }
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif
/* 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; }
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif
FernandoArielBeunza79156
257
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCAP_MSGSIZE) #define MODPLCAP_MSGSIZE 0 #endif
/* 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); }
/* 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
/* 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. */
/* 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
0x00 0x01
/* 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
FernandoArielBeunza79156
263
#endif
264
FernandoArielBeunza79156
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif
/* 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__; }
FernandoArielBeunza79156
265
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif
/* 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); }
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif
/* 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); }
FernandoArielBeunza79156
267
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif
/* 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); }
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif
/* 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
FernandoArielBeunza79156
271
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif
/* 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; }
272
FernandoArielBeunza79156
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif
/* 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); }
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif
FernandoArielBeunza79156
273
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif
/* 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; }
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif
276
FernandoArielBeunza79156
/* 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; }
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif
/* 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
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif
/* 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); }
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCPP_MSGSIZE) #define MODPLCPP_MSGSIZE 0 #endif
FernandoArielBeunza79156
279
/* 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); }
/* 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
/* 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
282
FernandoArielBeunza79156
#endif
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif
/* Definicin de SFR necesarias. */ __sfr __at (0x8a) SIO_TL0; __sfr __at (0x8c) SIO_TH0; __sbit __at (0x8c) SIO_TR0;
FernandoArielBeunza79156
283
/* 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__; }
284
FernandoArielBeunza79156
/* 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; }
FernandoArielBeunza79156
285
/* 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; }
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif
/* 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); }
FernandoArielBeunza79156
287
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif
/* 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); }
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif
/* 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
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif
/* 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
FernandoArielBeunza79156
291
/* 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; }
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif
/* Declaracin de funciones privadas. */ #if defined SDCC_MODEL_SMALL short int __modplcsp_sendcmd0__(__data modplcsp_hd *, char);
FernandoArielBeunza79156
293
/* 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); }
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif
/* 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; }
FernandoArielBeunza79156
295
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif
/* 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;
/* 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; } }
296
FernandoArielBeunza79156
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif
/* 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;
/* 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; }
FernandoArielBeunza79156
297
/* 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'); }
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif
/* 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'); } }
FernandoArielBeunza79156
299
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif
/* 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'); }
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif
/* 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
/* Verifica si se encuentra definido el tamao mximo del mensaje. */ #if !defined(MODPLCSP_MSGSIZE) #define MODPLCSP_MSGSIZE 0 #endif
/* Implementacin de funciones privadas. */ /* Funcin __modplcsp_waitchar__: Espera la recepcin del caracter especificado. */ void __modplcsp_waitchar__(char ch) { while(getchar() != ch); }
302
FernandoArielBeunza79156
#endif
/* 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
/* 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
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.
/* 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
/* 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
#endif
/* Archivos includos necesarios. */ #include "config.h" #include <stdio.h> #include <windows.h> #include <process.h> #include "modplcsp.h"
FernandoArielBeunza79156
307
/* 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
/* 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
/* 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;
/* 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
/* 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
/* 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. */
312
FernandoArielBeunza79156
/* 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
/* 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;
/* 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
/* 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
/* 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; }
316
FernandoArielBeunza79156
/* 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. */
/* 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
FernandoArielBeunza79156
317
/* 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
#endif
/* 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
/* 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
FernandoArielBeunza79156
321
/* 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
FernandoArielBeunza79156
323
/* 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
FernandoArielBeunza79156
325
/* 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
/* 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;
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
/* 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
/* 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
/* 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;
FernandoArielBeunza79156
329
330
FernandoArielBeunza79156
#endif
/* 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 *);
/* 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;
FernandoArielBeunza79156
331
332
FernandoArielBeunza79156
FernandoArielBeunza79156
333
334
FernandoArielBeunza79156
FernandoArielBeunza79156
335
/* 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
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.
/* 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
FernandoArielBeunza79156
337
/* 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
FernandoArielBeunza79156
339
/* 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;
/* 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
#endif
/* 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
/* 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
/* 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
344
FernandoArielBeunza79156
/* 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
/* 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. */
/* 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
/* 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
/* 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
/* 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
/* 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
/* 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
/* 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;
/* 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
/* 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
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.
/* 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
/* 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
/* 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
356
FernandoArielBeunza79156
/* 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
#endif
/* 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;
358
FernandoArielBeunza79156
/* 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;
/* 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
/* 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
/* 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
362
FernandoArielBeunza79156
/* 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
/* 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
/* 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
/* 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;
/* 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
/* 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
/* 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
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
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.
/* 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'
MODPLC_NORMRESET
370
FernandoArielBeunza79156
/* 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
/* 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
/* 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
#endif
/* Archivos includos necesarios. */ #include "config.h" #include <stdio.h> #include <windows.h> #include <process.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, size_t buffsize) { /* Variables. */ DWORD tid; DCB icfg;
/* 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
374
FernandoArielBeunza79156
/* 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
/* 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
/* 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
/* 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;
/* 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
378
FernandoArielBeunza79156
FernandoArielBeunza79156
379
380
FernandoArielBeunza79156
#endif
FernandoArielBeunza79156
381
/* 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
FernandoArielBeunza79156
383
/* 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
/* 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
"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
/* 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
/* 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
"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
/* 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
/* 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
/* 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
/* 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
/* 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",
/* 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
"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
/* 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
FernandoArielBeunza79156
397
398
FernandoArielBeunza79156
FernandoArielBeunza79156
399
/* 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
#endif
/* Archivos includos necesarios. */ #include "config.h" #include <windows.h> #include <process.h> #include "modplc.h" #include "modsp.h"
/* 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;
/* Crea un nuevo manejador de interfaz con la capa de sesin del modem PLC. */ handle = (modsp_hd *) malloc(sizeof(modsp_hd));
FernandoArielBeunza79156
401
/* Resultado de la operacin. */
/* Verifica que el manejador de interfaz con la capa de sesin del modem PLC exista. */
402
FernandoArielBeunza79156
/* 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
/* 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
/* 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
/* 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;
/* 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;
406
FernandoArielBeunza79156
/* 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; }
FernandoArielBeunza79156
407
/* 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
#endif
FernandoArielBeunza79156
409
/* Archivos includos necesarios. */ #include "config.h" #include <windows.h> #include <process.h> #include "modplc.h" #include "moddl.h"
/* 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;
/* 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
/* 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
412
FernandoArielBeunza79156
/* 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
/* 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
/* 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
/* 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
/* 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;
/* 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
/* 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
/* 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
#endif
FernandoArielBeunza79156
419
/* Archivos includos necesarios. */ #include "config.h" #include <windows.h> #include <process.h> #include "modplc.h" #include "modphy.h"
/* 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
/* 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
422
FernandoArielBeunza79156
/* 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
/* 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
/* 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
/* 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
/* 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. */
FernandoArielBeunza79156
427
#endif
/* 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__;
/* 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);
428
FernandoArielBeunza79156
/* 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
/* 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
/* 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
432
FernandoArielBeunza79156
/* 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
434
FernandoArielBeunza79156
FernandoArielBeunza79156
435
/* 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
FernandoArielBeunza79156
437
438
FernandoArielBeunza79156
FernandoArielBeunza79156
439
/* 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
FernandoArielBeunza79156
441
442
FernandoArielBeunza79156
/* 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
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.
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
/* 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
/* 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
/* 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
#endif
/* 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
/* 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
/* 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
/* 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
/* 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
452
FernandoArielBeunza79156
/* 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
/* 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;
/* 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
/* 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. */
/* 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
/* 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; }
456
FernandoArielBeunza79156
/* 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. */
/* 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
FernandoArielBeunza79156
457
/* 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
#endif
/* 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 *);
FernandoArielBeunza79156
459
/* 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
FernandoArielBeunza79156
461
/* 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
FernandoArielBeunza79156
463
/* 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
FernandoArielBeunza79156
465
/* 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
/* 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); }
/* 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;
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
/* 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
/* 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
#endif
FernandoArielBeunza79156
469
/* Archivos includos necesarios. */ #include "config.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "modplcpp.h" #include "modplcap.h"
/* 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;
/* 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
FernandoArielBeunza79156
471
472
FernandoArielBeunza79156
FernandoArielBeunza79156
473
474
FernandoArielBeunza79156
/* 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; }
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
/* 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
/* 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
/* 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
#endif
/* 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
/* 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
/* 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
FernandoArielBeunza79156
481
/* 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
/* 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
484
FernandoArielBeunza79156
/* 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
/* 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
/* 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
/* 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
/* 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
/* 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;
/* 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
/* 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
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.
/* 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
#if !defined(__MODPLCPHY_H__)
492
FernandoArielBeunza79156
/* 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
/* 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
#endif
494
FernandoArielBeunza79156
/* 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
/* 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
/* 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
/* 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
FernandoArielBeunza79156
499
/* 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
/* 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
/* 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
/* 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;
/* 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
/* 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
/* 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
/* 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; }
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
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.
/* 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
MODPLC_NORMRESET '1' '2' '3' '4' '5' '6' '7' '8' '9' 'a'
/* 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
/* Interfaz con el modem PLC. */ /* Tamaoo del buffer. */ #define MODPLC_BUFFERSIZE /* Cantidad de bytes de una lnea por envo. */ #define MODPLC_FRAGMENTLINESIZE
4096
#endif
/* 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
#endif
/* 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];
/* 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
/* Verifica la validez del manejador de la interfaz de comunicacin por puerto serie. */ if (!hd) return 0; /* Enva un mensaje. */ sent = 0;
FernandoArielBeunza79156
511
/* 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); }
512
FernandoArielBeunza79156
/* 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
/* 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
514
FernandoArielBeunza79156
FernandoArielBeunza79156
515
#endif
/* 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
FernandoArielBeunza79156
517
/* 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
/* 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];
FernandoArielBeunza79156
519
/* 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
/* 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
/* 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
/* 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
"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
/* 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
"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
/* 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
/* 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
/* 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,
/* 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];
/* 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
/* 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
/* 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
532
FernandoArielBeunza79156
FernandoArielBeunza79156
533
/* 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
FernandoArielBeunza79156
535
#endif
/* Archivos includos necesarios. */ #include "config.h" #include <pthread.h> #include "modplc.h" #include "modsp.h"
/* 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;
/* 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
/* 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
/* 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
FernandoArielBeunza79156
539
/* 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
/* 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. */
FernandoArielBeunza79156
541
/* Definicin de tipos. */ /* Direccin fsica del modem PLC. */ typedef unsigned char moddl_phyaddr[8]; /* Direccin lgica del modem PLC. */
542
FernandoArielBeunza79156
/* 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
#endif
544
FernandoArielBeunza79156
/* 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;
/* 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
/* 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
FernandoArielBeunza79156
547
548
FernandoArielBeunza79156
/* 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
/* 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
/* 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
/* 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;
/* 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
/* 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
/* Declaracin de funciones pblicas. */ /* Funcin modphy_init: Inicializa los recursos utilizados por la capa fsica del modem PLC. */
FernandoArielBeunza79156
553
554
FernandoArielBeunza79156
#endif
/* Archivos includos necesarios. */ #include "config.h" #include <pthread.h> #include "modplc.h" #include "modphy.h" #include "moddl.h"
/* 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
/* 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
/* 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
/* 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
/* 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
/* 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
/* 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
/* 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); }
562
FernandoArielBeunza79156
/* 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
FernandoArielBeunza79156
563
/* 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__;
/* 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;
/* 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
/* 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
/* 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
/* 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
568
FernandoArielBeunza79156
/* 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
570
FernandoArielBeunza79156
FernandoArielBeunza79156
571
/* Procesa solicitudes destinadas a la capa de enlace del modem PLC. */ dlconnhd = NULL; while(!hd->stopflag) { /* Recibe el cdigo de operacin. */
572
FernandoArielBeunza79156
FernandoArielBeunza79156
573
574
FernandoArielBeunza79156
FernandoArielBeunza79156
575
576
FernandoArielBeunza79156
/* 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
578
FernandoArielBeunza79156
FernandoArielBeunza79156
579
/* Enva los datos. */ received = 0; ptr = (unsigned char *) stream; while((stream) && (received < size)) { lastreceive = read(hq, ptr + received, size - received); received += lastreceive; } return 1; }
/* Archivos includos necesarios. */ #include "config.h" #include <stdio.h> #include <string.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. */
580
FernandoArielBeunza79156
/* 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;
/* 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
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
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.
FernandoArielBeunza79156
583
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
/* 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
FernandoArielBeunza79156
585
20
/* 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" '$'
MODPLC_NORMRESET "1" "2" "3" "4" "5" "6" "7" "8" "9" "a"
MODPLC_NORMRESET "1" "2" "3" "4" "5" "6" "7" "8" "9" "a"
586
FernandoArielBeunza79156
#endif
/* Definicin de funciones pblicas. */ /* Funcin wait_usecs: Espera el transcurso de una determinada microsegundos. */ void wait_usecs(long int);
#endif
/* 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
#include "../common/serial.h"
#include "../common/serial.c"
588
FernandoArielBeunza79156
FernandoArielBeunza79156
589
#endif
/* 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
/* 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
/* 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
/* 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
/* 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
/* 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
/* Implementacin de funciones privadas. */ /* Interrupcin INT0: Procesa la seal recibida. */ void __phy_int0__(void) __interrupt 0 { cli();
596
FernandoArielBeunza79156
/* 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
; ;
FernandoArielBeunza79156
597
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.
598
FernandoArielBeunza79156
/* 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,
FernandoArielBeunza79156
599
/* 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
/* Archivos includos necesarios. */ #include "config.h" #include <string.h> #include "common.h" #include "phy.h" #include "mac.h"
(2 * (MAC_HEADERSIZE + \ MAC_FCSSIZE))
/* 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
/* 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;
/* 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
/* 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
604
FernandoArielBeunza79156
FernandoArielBeunza79156
605
606
FernandoArielBeunza79156
/* 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
608
FernandoArielBeunza79156
/* 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
/* 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
/* Definicin de funciones pblicas. */ /* Funcin llc_init: Inicializa los recursos utilizados por la subcapa LLC. */ void llc_init(void); /* Funcin llc_release:
FernandoArielBeunza79156
611
#endif
612
FernandoArielBeunza79156
/* 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. */
/* 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
/* 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
/* 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. */
FernandoArielBeunza79156
615
/* 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; }
616
FernandoArielBeunza79156
/* 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
/* Archivos includos necesarios. */ #include "config.h" #include "common.h" #include <string.h> #include "llc.h"
FernandoArielBeunza79156
617
/* Definicin de tipos. */ /* Mensaje ARP. */ typedef struct { unsigned char type; unsigned char protocol; arp_logaddr address; } __arp_msg__;
/* 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
/* 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
/* 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
/* 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__)); }
FernandoArielBeunza79156
621
/* Definicin de tipos. */ /* Direccin fsica de dispositivo. */ typedef llc_addr dl_addr; /* Direccin lgica de dispositivo. */ typedef arp_logaddr dl_logaddr;
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
#endif
/* 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
624
FernandoArielBeunza79156
/* 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 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
#endif
626
FernandoArielBeunza79156
/* 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];
/* 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;
/* 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
/* 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
/* 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
/* 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;
/* Agrega el nuevo identificador de mensaje a cada una de las interfaces. */ result = 0; for(iface = 0; iface < NET_PHYINTERFACES; iface++)
630
FernandoArielBeunza79156
/* 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;
/* Obtiene la interfaz con la menor capacidad mxima de bytes que puede contener un mensaje. */
FernandoArielBeunza79156
631
/* 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
/* 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; }
FernandoArielBeunza79156
633
/* Definicin de tipos. */ /* Identificador de grupo. */ typedef unsigned char tp_grpid; /* Encabezado del mensaje. */ typedef struct { unsigned char version; char sequence; } __tp_header__;
/* 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
#endif
/* 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__;
/* 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
/* 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
FernandoArielBeunza79156
637
638
FernandoArielBeunza79156
/* 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
/* 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; }
640
FernandoArielBeunza79156
/* Definicin de tipos. */ /* Identificador de grupo. */ typedef unsigned char sp_grpid; /* Encabezado del mensaje. */ typedef struct { unsigned char version; } __sp_header__;
/* 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
#endif
/* 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;
642
FernandoArielBeunza79156
FernandoArielBeunza79156
643
644
FernandoArielBeunza79156
/* 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); }
FernandoArielBeunza79156
645
/* 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);
/* 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
/* 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
648
FernandoArielBeunza79156
/* 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
/* 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
FernandoArielBeunza79156
651
/* 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
/* Enva los datos. */ reset_watchdog(); ptr = (char *) &intval; printf("\\%02X\\%02X\r\n", ptr[1], ptr[0]);
FernandoArielBeunza79156
653
/* 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
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.
FernandoArielBeunza79156
655
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
656
FernandoArielBeunza79156
#endif
/* 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
/* 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;
/* 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
/* 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
660
FernandoArielBeunza79156
/* 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%=
; ; ; ; ; ; ; ; ; ; ; ;
\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
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)
); /* 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
; ; ; ; ; ; ;
662
FernandoArielBeunza79156
L_sndbit0%=:
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)
L_end1%=:
); /* 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
\n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\
FernandoArielBeunza79156
663
L_init%=:
664
FernandoArielBeunza79156
L_sndbit0_06_0%=:
FernandoArielBeunza79156
665
%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
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
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%=:
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
FernandoArielBeunza79156
667
r2 r10 r4 r8 r15
%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
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
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
%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
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%=
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
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
); } /* 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;
; ; ; ; ; ;
672
FernandoArielBeunza79156
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
\n\t\ \n\t\ \n\t\ \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%=:
; ; ; ; ; ; ;
FernandoArielBeunza79156
673
/* 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
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
Inicializa el integrador.
\n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \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
%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
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
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
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
FernandoArielBeunza79156
677
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 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
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%=:
L_calth_rx_8%=:
r11, r16 %1, r11 r11, r16 r20 %8, r20 L_calth_rx_10%=
FernandoArielBeunza79156
679
L_calth_rx_10%=:
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
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%=:
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
FernandoArielBeunza79156
681
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
682
FernandoArielBeunza79156
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
L_cont_rx_2%=:
L_start_rx_1%= L_end_2%= r16, 0x00 %1, r16 %2, %3 r16, 0x1a r16 L_wait_rx_2%=
Reinicia el integrador.
L_wait_rx_2%=:
FernandoArielBeunza79156
683
_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
L_wait_0%=:
L_sense_ch%=:
FernandoArielBeunza79156
685
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_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
\n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\
686
FernandoArielBeunza79156
FernandoArielBeunza79156
687
r18, 7 L_genbit1%= %0, %0, %0, %0, %0, %0, r8 r14 r16 r15 r11 r9
L_genbit0_0%=:
%0, r2
L_genbit0_1%=:
688
FernandoArielBeunza79156
%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
%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
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
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
\n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \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
L_continue%=:
%0, r8
%0, r9
%0, r8
%0, r7
%0, r6
%0, r5
%0, r4
%0, r3
692
FernandoArielBeunza79156
%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
; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;
\n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \n\t\ \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
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)
694
FernandoArielBeunza79156
; ; ; ; ; ; ; ; ;
\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\ "
/* 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; }
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
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.
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
#include "../common/common.h"
#include "../common/common.c"
#include "../common/serial.h"
#include "../common/serial.c"
FernandoArielBeunza79156
697
#endif
/* 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
/* 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
#endif
/* 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;
/* 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
/* 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
/* 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
/* 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
/* /* /* /* /* /* /* /* /* /* /*
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
FernandoArielBeunza79156
705
/* Archivos includos necesarios. */ #include "config.h" #include <stdio.h> #include <at89x52.h> #include "memory.h" #include "interrupts.h" #include "serial.h" #include "common.h"
/* 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
a la reinicializacin
a la lectura del
a la escritura del
a la verificacin del
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
Archivo serial.c: en este archivo se encuentran implementadas las primitivas declaradas en el archivo serial.c.
/* 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
FernandoArielBeunza79156
709
#endif
/* Definicin de SFR necesarias. */ __sfr __at (0xa7) WDTPRG; __sfr __at (0xa6) WDTRST;
/* 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
/* 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
/* /* /* /*
/* 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
/* 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;
/* 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
/* 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
; ; ; ; ;
/* 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
/* 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
/* 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 }
FernandoArielBeunza79156
717
#endif
/* 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
/* 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
720
FernandoArielBeunza79156
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++.
FernandoArielBeunza79156
721
/* 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
/* Declaracin de clases. */ /* Clases declaradas. */ class modplcapcpp; class modplcapcpp_msg; /* Clase modplcapcpp */ class modplcapcpp { /* Atributos y mtodos privados. */ private: modplcap_hd *handle;
/* 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
/* 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
/* 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
/* 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
726
FernandoArielBeunza79156
/* 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
/* Declaracin de clases. */ /* Clases declaradas. */ class modplcapcpp; class modplcapcpp_msg; /* Clase modplcapcpp */ class modplcapcpp { /* Atributos y mtodos privados. */ private: modplcap_hd *handle;
/* Mtodos pblicos. */
FernandoArielBeunza79156
727
/* Manejador de mensaje. */
/* Mtodos pblicos. */ public: /* Constructor: Crea un nuevo mensaje. */ modplcapcpp_msg(modplcapcpp *, modplcapcpp_grpid, modplcapcpp_msgid); /*
728
FernandoArielBeunza79156
/* 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
/* 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
FernandoArielBeunza79156
731
#endif
732
FernandoArielBeunza79156
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.
FernandoArielBeunza79156
733
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.
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
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.
Bloques Simulink
Capa de aplicacin
modplcap.dll
En la figura E7 se puede observar la organizacin de los elementos descriptos dentro del esquema de capas propuesto en el presente trabajo.
/* Definicin de tipos. */ /* Estructura de nodo de lista de mensajes recibidos. */ typedef struct { modplcap_msg *msg; void *next; } listmsg_node;
/* 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
/* 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;
/* 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;
/* Verifica que manejador de comunicacin entre bloques Simulink del Modem PLC exista. */ if (!handle) return 0;
738
FernandoArielBeunza79156
/* 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
/* 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
/* 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
742
FernandoArielBeunza79156
/* 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
/* 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
FernandoArielBeunza79156
745
/* 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. */
746
FernandoArielBeunza79156
FernandoArielBeunza79156
747
748
FernandoArielBeunza79156
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
/* 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
/* 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;
/* 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
/* Definido por Simulink. */ #ifdef MATLAB_MEX_FILE #include "simulink.c" #else #include "cg_sfun.h" #endif
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;
/* 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
/* 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
int *flag_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
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
/* 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
/* 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;
/* 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
/* Definido por Simulink. */ #ifdef MATLAB_MEX_FILE #include "simulink.c" #else #include "cg_sfun.h" #endif
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
/* 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;
/* 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
int *flag_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
/* Definido por Simulink. */ #ifdef MATLAB_MEX_FILE #include "simulink.c" #else #include "cg_sfun.h" #endif
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;
/* 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
/* 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;
/* 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
/* 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
Modem_PLC_Get_Field 2
FernandoArielBeunza79156
761
/* 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;
762
FernandoArielBeunza79156
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
/* Definido por Simulink. */ #ifdef MATLAB_MEX_FILE #include "simulink.c" #else #include "cg_sfun.h" #endif
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
/* 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
/* Definido por Simulink. */ #ifdef MATLAB_MEX_FILE #include "simulink.c" #else #include "cg_sfun.h" #endif
766
FernandoArielBeunza79156
FernandoArielBeunza79156
767
768
FernandoArielBeunza79156
FernandoArielBeunza79156
769
770
FernandoArielBeunza79156
/* 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;
/* 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
/* Funcin main: Funcin principal. */ void main(void) { /* Variables. */ unsigned short i; __data modplcap_hd *hd;
/* P1 P0 P2 P3
/* Inicializa el estado de las luces. */ lights = 0x00; side = (P1 >> 3) & 0x01; /* Ciclo de ejecucin. */
772
FernandoArielBeunza79156
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
774
FernandoArielBeunza79156
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.
FernandoArielBeunza79156
775
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.
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.
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).
FernandoArielBeunza79156
777
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.
778
FernandoArielBeunza79156
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.
/* 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
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
/* 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
FernandoArielBeunza79156
781
782
FernandoArielBeunza79156
/* 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
: ");
: ");
: ");
/* 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
/* 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
/* 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
FernandoArielBeunza79156
787
/* 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
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. */
788
FernandoArielBeunza79156
FernandoArielBeunza79156
789
790
FernandoArielBeunza79156
FernandoArielBeunza79156
791
/* 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
FernandoArielBeunza79156
793
794
FernandoArielBeunza79156
/* 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
796
FernandoArielBeunza79156
FernandoArielBeunza79156
797
798
FernandoArielBeunza79156
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