//! An Peer was removed. Remove this device from the current list of devices void TSMADataMaster_OnEventPeerRemoved(TGenDriverEvent * event) { TNetDevice * dev; WORD netaddr = 0; //try to resolve from "DriverDeviceHandle" to the right device pointer if (TRoute_FindAddrByDriverDevicePeer(event->DriverID, event->EventData.DriverDeviceHandle, &netaddr) && (dev = TPlant_FindDevAddr(netaddr)) != NULL) { /*Master command to detect the new device...*/ TMasterCmdReq * mc = TMasterCmdFactory_GetMasterCmd( MC_REMOVE_DEVICE ); mc->OnEnd = TSMADataMaster_OnEventMasterCmdEnded; mc->Param.DevHandle = TNetDevice_GetHandle( dev ); YASDI_DEBUG((VERBOSE_ERROR,"TSMADataMaster_OnEventPeerRemoved(): " "Removing Device '%s', DriverDevHandle=%d\n", TNetDevice_GetName( dev ), event->EventData.DriverDeviceHandle )); /*Send master command (async)...*/ TSMADataMaster_AddCmd( mc ); } else { YASDI_DEBUG((VERBOSE_ERROR,"TSMADataMaster_OnEventPeerRemoved(): " "Unknown device to remove, DriverDevHandle=0x%x...\n", event->EventData.DriverDeviceHandle)); } }
/************************************************************************** Description : Ereignis: Ein Antwort eines IORequest wurde empfangen. Parameter : instance = Masterinstanz req = Referenz auf den entsprechenden IORequest SourceAddr = Absender der Antwort Buffer = Referenz auf Datenpuffer BufferSize = Groesse der Daten RxFlags = Empfangsflags Return-Value : --- Changes : Author, Date, Version, Reason ******************************************************** PRUESSING, 30.05.2001, 1.0, Created **************************************************************************/ void TStateDetect_OnIOReqPktRcv(TMasterCmdReq * mc, struct _TIORequest * req, TOnReceiveInfo * rcvInfo) { TNetDevice * NewDev; BOOL bIsDeviceNew = FALSE; UNUSED_VAR ( req ); /* Antwort interpretieren: Neues Geraet, falls noch nicht im Geraetebaum eingetragen, nun eintragen... */ NewDev = TPlant_ScanGetNetBuf( &Plant, rcvInfo->Buffer, rcvInfo->BufferSize, rcvInfo->SourceAddr, rcvInfo->RxFlags, &bIsDeviceNew, rcvInfo->BusDriverDevHandle); if (NewDev) { #ifdef DEBUG BOOL sunnyNet = rcvInfo->RxFlags & TS_PROT_SUNNYNET_ONLY; #endif YASDI_DEBUG(( VERBOSE_MASTER, "TStateDetect::OnIOReqPktRcv() Device answer" ": Device type='%8s' SN=%10ld NetAddr=[0x%04x], prot=%s\n", TNetDevice_GetType( NewDev ), TNetDevice_GetSerNr( NewDev ), TNetDevice_GetNetAddr( NewDev ), sunnyNet ? "SUNNYNET" : "SMANET") ); if (!TDeviceList_IsInList( mc->NewFoundDevList, NewDev )) { /* In die Liste der gerade gefunden Geraet aufnehmen */ TDeviceList_Add( mc->NewFoundDevList, NewDev ); } if (bIsDeviceNew) { //Callback Master API Event listener... TSMADataMaster_FireAPIEventDeviceDetection( YASDI_EVENT_DEVICE_ADDED, TNetDevice_GetHandle( NewDev ), 0 /*unused*/); } } else { YASDI_DEBUG(( VERBOSE_MASTER, "TStateDetect::OnIOReqPktRcv() Netzerfassung-Geraetemeldung" " ist ungueltig!" " Paket wird ignoriert! SrcAddr=%d BufferSize=%ld\n", rcvInfo->SourceAddr, rcvInfo->BufferSize)); } }
void TStateConfig_OnIOReqEnd( TMasterCmdReq * mc, struct _TIORequest * req ) { assert(mc && req); /* Wenn der IORequest erfolgreich war, dann weiter */ if (req->Status == RS_SUCCESS) YASDI_DEBUG(( VERBOSE_MASTER, "TStateConfig::OnIOReqEnd(): Device configured.\n")); else YASDI_DEBUG(( VERBOSE_MASTER, "TStateConfig::OnIOReqEnd(): Device NOT configured!\n")); TStateConfig_CheckNextDevice( mc ); }
void TStateConfig_OnIOReqPktRcv( TMasterCmdReq * mc, struct _TIORequest * req, TOnReceiveInfo * recvInfo) { TNetDevice * dev; DWORD sn = 0; UNUSED_VAR ( mc ); UNUSED_VAR ( req ); YASDI_DEBUG((VERBOSE_MASTER, "TStateConfig::OnIOReqPktRcv() !\n")); //Dateninhalt ist die Seriennummer des geantworteten Geraetes if (recvInfo->BufferSize >= 4) { sn = le32ToHost(recvInfo->Buffer); //Suche das Geraet, das geantwortet hat, im eigenen Ger�ebaum... dev = TPlant_FindSN( sn ); if (dev) { //Die Netzadresse des Geraetes uebernehmen... TNetDevice_SetNetAddr( dev, recvInfo->SourceAddr ); } } }
/************************************************************************** Description : Ereignis: Der IORequest wird beendet Parameter : instance = Masterinstanz req = Referenz auf den entsprechenden IORequest Return-Value : --- Changes : Author, Date, Version, Reason ******************************************************** PRUESSING, 30.05.2001, 1.0, Created **************************************************************************/ void TStateDetect_OnIOReqEnd( TMasterCmdReq * mc, struct _TIORequest * req) { UNUSED_VAR ( mc ); UNUSED_VAR ( req ); YASDI_DEBUG(( VERBOSE_MASTER, "TStateDetect::OnIOReqEnd(): Currently detected devices in plant: %u; " "Searching for %u device(s)!\n", TDeviceList_GetCount( Plant.DevList ), mc->wDetectDevMax )); /* Wenn Geraete gefunden wurden, gehe in den Zustand "Konfiguration" */ if (!TDeviceList_IsEmpty( mc->NewFoundDevList ) ) { /* state "Configuration" */ TSMADataCmd_ChangeState( mc, TStateConfig_GetInstance() ); } else { /* stay in state "Detection" and check for retries */ TSMADataCmd_ChangeState( mc, TStateDetect_GetInstance() ); } }
//! Called when an master command ends which was self added by an bus event... void TSMADataMaster_OnEventMasterCmdEnded( struct _TMasterCmdReq * mc) { YASDI_DEBUG((VERBOSE_MESSAGE,"TSMADataMaster_OnEventMasterCmdEnded(): " " Event finished (type=%d)\n", mc->CmdType)); //only free the command. That's it... TMasterCmdFactory_FreeMasterCmd( mc ); }
void TStateConfig_OnEnter( TMasterCmdReq * mc ) { YASDI_DEBUG(( VERBOSE_MASTER, "TStateConfig::OnEnter\n" )); /* Iterator zum Iterieren der Geraeteliste */ mc->NewFoundDevListIter=0; /* Iteration starten... */ TStateConfig_CheckNextDevice( mc ); }
/************************************************************************** Description : Deinitialization of the Yasdi-Shared-Library Parameter : --- Return-Value : --- Changes : Author, Date, Version, Reason ******************************************************** PRUESSING, 23.12.2001, 1.0, Created **************************************************************************/ SHARED_FUNCTION void yasdiShutdown(void) { YASDI_DEBUG(( VERBOSE_MESSAGE, "YASDI calling yasdiShutdown...\n" )); /*Using Statistic Writer?*/ TStatisticWriter_Destructor(); //TSMAData-Destructor... TSMAData_destructor(); //destroy the repository... TRepository_Destroy(); YASDI_DEBUG(( VERBOSE_MESSAGE, "Yasdi-Library is down...\n" )); //cleanup os layer (close debug out system) os_cleanup(); }
/************************************************************************** * * NAME : <Name> * * DESCRIPTION : Bus Event dispatcher * An bus event has occurred... * * *************************************************************************** * * IN : --- * * OUT : --- * * RETURN : --- * * THROWS : --- * **************************************************************************/ void TSMADataMaster_OnBusEvent(TGenDriverEvent * event) { assert(event); YASDI_DEBUG((VERBOSE_MASTER, "TSMADataMaster_OnBusEvent(eventType=%d)...\n", (int)event->eventType )); busevents++; //dispatch events... switch(event->eventType) { case DRE_BUS_CONNECTED: TSMADataMaster_OnEventBusConnected(event); break; case DRE_PEER_ADDED: TSMADataMaster_OnEventPeerAdded(event); break; case DRE_PEER_REMOVED: TSMADataMaster_OnEventPeerRemoved(event); break; default: YASDI_DEBUG((VERBOSE_ERROR, "TSMADataMaster_OnBusEvent(): Unknown event...\n", (int)event->eventType )); } }
/************************************************************************** Description : Erzeugt zu einem Device das benoetigte Protokoll- Implementierungs-Object Parameter : Pointer to device Return-Value : Pointer to new created protocol object Changes : Author, Date, Version, Reason ******************************************************** PRUESSING, 20.04.2001, 1.0, Created **************************************************************************/ void TProtLayer_CreateProtocol(TDevice * device) { int i; char cProtName[30]; char ConfigPath[50]; struct TProtocol * prot = NULL; TProtocolMapEntry * newentry; /* count of prots... */ int iProtCount = sizeof(ProtocolTable) / sizeof(struct TProtocolTable); assert(device); /* ** get the right protocol name from config file */ sprintf(ConfigPath,"%s.Protocol",device->cName); TRepository_GetElementStr(ConfigPath, "SMANet", cProtName, sizeof(cProtName)); /* Rufe den richtigen Konstruktor zum Erzeugen des Protokolls auf...*/ for(i = 0; i < iProtCount; i++) { if (strstr(cProtName, ProtocolTable[i].ProtName ) != NULL ) { assert(ProtocolTable[i].Constructor); prot = (ProtocolTable[i].Constructor)(); YASDI_DEBUG((VERBOSE_MESSAGE,"Configured protocol for device '%5s' is: '%s'...\n", device->cName, ProtocolTable[i].ProtName )); //Eintragen... newentry = os_malloc(sizeof(TProtocolMapEntry)); assert(newentry); newentry->device = device; newentry->protocol = prot; ADDHEAD( &ProtocolMap, &newentry->node ); } } }
/************************************************************************** Description : Initialization of the Yasdi-Shared-Library Parameter : cIniFileName = Pointer to the configuration file (INI-File) of yasdi; If this parameter is NULL yasdi will use the default configuration file "yasdi.ini" in the current directory Return-Value : 0: ok, -1: error reading config file Changes : Author, Date, Version, Reason ******************************************************** PRUESSING, 23.12.2001, 1.0, Created **************************************************************************/ SHARED_FUNCTION int yasdiInitialize(const char * cIniFileName, DWORD * pDriverCount) { int iRes = 0; if (cIniFileName) strcpy( ProgPath, cIniFileName ); else ProgPath[0] = 0; //Construct first the repository (to get configs) TRepository_Init(); /* ** Wo sollen saemtliche Debug-Meldungen ausgegeben werden? ** Unter Linux werden diese default nach "/dev/null" ausgeben sonst nach "stderr" */ { FILE * fd = NULL; char DebugFile[100]={0}; TRepository_GetElementStr( "Misc.DebugOutput","", DebugFile, sizeof(DebugFile)-1 ); if (strlen(DebugFile)>0) { //console stderr ? if (strcmp(DebugFile, "stderr") == 0) fd = stderr; else if(strcmp(DebugFile, "stdout") == 0) fd = stdout; else { //into file /* bei Relativ-Pfad in des Yasdi-Verzeichnis... */ if(Tools_PathIsRelativ(DebugFile)) { //Pfad relativ zum Konfiguationsfile... char p[200]={0}; strcat(p,ProgPath); Tools_PathAdd(p, DebugFile); strcpy(DebugFile,p); } fd = fopen(DebugFile,"w"); } if (fd) { /* Pufferung abschalten */ setbuf(fd,0); } } //configure the debug output... os_setDebugOutputHandle(fd); } YASDI_DEBUG(( VERBOSE_MESSAGE, "YASDI Library V" LIB_YASDI_VERSION_FULL " (%s)\n" SMA_COPYRIGHT "\n" "Compile time: " __TIME__ " " __DATE__ "\n\n", os_GetOSIdentifier())); /* * Call the contructor of the SMAData-Layer...that's all */ TSMAData_constructor(); //Get the count of loaded drivers... assert(pDriverCount); *pDriverCount = TDriverLayer_GetDriverCount(); if (0 == *pDriverCount) { YASDI_DEBUG((VERBOSE_WARNING,"WARNING: No YASDI drivers loaded! This makes no sense!\n")); iRes = -1; } /*Using Statistic Writer?*/ TStatisticWriter_Constructor(); return iRes; }
void TStateConfig_CheckNextDevice( TMasterCmdReq * mc ) { TNetDevice * dev; assert(mc->NewFoundDevList); dev = GET_NEXT_DEVICE(mc->NewFoundDevListIter, mc->NewFoundDevList->DevList); if (dev) { BOOL bAddressMustChanged = false; WORD OrigNetAddr, NewNetAddr; OrigNetAddr = TNetDevice_GetNetAddr( dev ); /* collision of network address? => changing... */ if (TPlant_CheckNetAddrCollision( &Plant, dev )) { YASDI_DEBUG((VERBOSE_MASTER, "TStateConfig::CheckNextDevice(): " "Net address collision of Device '%s'! Changing...\n", TNetDevice_GetName(dev) )); bAddressMustChanged = true; } /* Device has the same adress of the master? => Changing */ if (TNetDevice_GetNetAddr(dev) == 0) { YASDI_DEBUG((VERBOSE_MASTER, "TStateConfig::CheckNextDevice(): " "Device '%s' has the same address of " "the master! => Changing...\n", TNetDevice_GetName(dev) )); bAddressMustChanged = true; } /* Check the address range of the device */ if (((TNetDevice_GetNetAddr(dev) & 0x00ff) < (int)Master.DeviceAddrRangeLow) || ((TNetDevice_GetNetAddr(dev) & 0x00ff) > (int)Master.DeviceAddrRangeHigh) ) { YASDI_DEBUG((VERBOSE_MASTER, "TStateConfig::CheckNextDevice(): " "Net address of Device '%s' is out of the allowed range!" " Allowed:[0x%x..0x%x] => Changing...\n", TNetDevice_GetName(dev), (int)Master.DeviceAddrRangeLow, (int)Master.DeviceAddrRangeHigh )); bAddressMustChanged = true; } /* Need to change the device address? => Changing... */ if (bAddressMustChanged) TNetDevice_SetNetAddr(dev, TPlant_GetUniqueNetAddr( &Plant, dev, Master.DeviceAddrRangeLow, Master.DeviceAddrRangeHigh ) ); /* BUS-ID ok? */ if ((TNetDevice_GetNetAddrBus(dev) < (int)Master.DeviceAddrBusRangeLow) || (TNetDevice_GetNetAddrBus(dev) > (int)Master.DeviceAddrBusRangeHigh)) { TNetDevice_SetNetAddrBus(dev, Master.DeviceAddrBusRangeLow); } /* String-ID ok?*/ if ((TNetDevice_GetNetAddrString(dev) < (int)Master.DeviceAddrBusRangeLow) || (TNetDevice_GetNetAddrString(dev) > (int)Master.DeviceAddrBusRangeHigh)) { TNetDevice_SetNetAddrString(dev, Master.DeviceAddrBusRangeLow); } /*restore original net address and get the new one */ NewNetAddr = TNetDevice_GetNetAddr(dev); TNetDevice_SetNetAddr( dev, OrigNetAddr ); /* Erzeuge IORequest fuer die Konfiguration */ /* CMD_GET_CFG_NETADR */ TSMAData_InitReqCfgNetAddr( mc->IOReq, Master.SrcAddr, /* eigene Netzadresse */ TNetDevice_GetSerNr( dev ), /* das angeprochene Geraet */ NewNetAddr, /* die neue Netzadresse des Geraetes */ 4, /* Timeout */ 5, /* Repeat */ dev->prodID //the transportprotocol.... ); YASDI_DEBUG(( VERBOSE_MASTER, "TStateConfig::CheckNextDevice(): Configure Device " "'%s' to address 0x%x...\n", TNetDevice_GetName( dev ), NewNetAddr )); TSMAData_AddIORequest( mc->IOReq ); } else { /* alle erfassten Geraete konfiguriert => In den Status "Detection" zurueckkehren */ //TDevListIter_Destructor( Master.DevIter ); TSMADataCmd_ChangeState( mc, TStateDetect_GetInstance() ); } }
/************************************************************************** Description : Ereignis: Der Status "Detection" ist aktiviert worden... Parameter : Referenz auf die Master - Instanz Return-Value : --- Changes : Author, Date, Version, Reason ******************************************************** PRUESSING, 30.05.2001, 1.0, Created PRUESSING, 18.08.2001, 1.1, Maximalanzahl der Erfassungversuche eingefuehrt PRUESSING, 05.10.2001, 1.2, Bearbeitung von Masterkommandos druchfuehren.... **************************************************************************/ void TStateDetect_OnEnter( TMasterCmdReq * mc ) { WORD useTransportProt = 0; BOOL broadbandDetection; YASDI_DEBUG(( VERBOSE_MASTER, "TStateDetect::OnEnter\n" )); /* Masterkommando jetzt in Bearbeitung...*/ mc->Result = MCS_WORKING; /* calculate the device count when searching for only one device more */ if(mc->wDetectDevMax == (WORD)DETECT_ONE_MORE_DEV) mc->wDetectDevMax = (WORD)(TPlant_GetCount() + 1); /* Schon alle Geraet erfasst? (unendliches Suchen=="-1"?) */ if ((TPlant_GetCount() < (DWORD)mc->wDetectDevMax) && (mc->iDetectMaxTrys != 0) ) { /* no, search ahead... */ //broadband (normal) or directed detection? //directed detection only when from event "peer added" initiated with //an valid "Driver Device Handle"... broadbandDetection = ( mc->Param.DriverDeviceHandle == INVALID_DRIVER_DEVICE_HANDLE ); /* Wenn NICHT unendliches Suchen (!= -1), dann ein Versuch weniger */ if (mc->iDetectMaxTrys > 0) mc->iDetectMaxTrys--; /* calculate the next transport protocol which should be used ** toggle also the "Master.bDetectionStart" flag */ useTransportProt = TSMADataMaster_CalcNextTransportProt( mc ); //init get net request TSMAData_InitReqGetNet( mc->IOReq, Master.SrcAddr, // eigene Netzadresse Master.Timeouts.iWaitAfterDetection, // Timeout in Sekunden useTransportProt, // transport prot. mc->bDetectionStart, // CMD_GET_NET or ..START ? broadbandDetection // broadband (normal) or directed detection? ); /* Die evtl. schon erfasst wurden, aus der Liste nehmen bei GET_NET */ if ( !mc->bDetectionStart ) TDeviceList_Clear( mc->NewFoundDevList ); YASDI_DEBUG((VERBOSE_MASTER, "TStateDetect:: Sende %s\n", mc->bDetectionStart ? "CMD_GET_NET_START" : "CMD_GET_NET")); /* Request absetzen */ TSMAData_AddIORequest( mc->IOReq ); } else { //stop seaching devices...(all found or not) YASDI_DEBUG(( VERBOSE_MASTER, "TStateDetect::OnEnter(): Device detection finished....\n" )); YASDI_DEBUG(( VERBOSE_MASTER, "TStateDetect ==> %ld Device(s) in plant," " searching %d device(s)!\n", TPlant_GetCount(), mc->wDetectDevMax )); //calculate the result of the detection: if (TPlant_GetCount() >= (DWORD)mc->wDetectDevMax) mc->Result = MCS_SUCCESS; //ok (all found) else mc->Result = MCS_TIMEOUT; //nok (not all found, signaled with "timeout" /* step into state identification and get all channel lists if needed... */ // The state "identification" end the master command... TSMADataCmd_ChangeState(mc, TStateIdent_GetInstance() ); } YASDI_DEBUG(( VERBOSE_MASTER, "TStateDetect::OnEnter() end....\n" )); }