extern "C" int VSCPBlockingReceive(long handle, vscpEvent *pEvent, unsigned long timeout) { int rv = 0; // Check pointer if ( NULL == pEvent) return CANAL_ERROR_PARAMETER; CRawEthernet *pdrvObj = theApp.getDriverObject(handle); if (NULL == pdrvObj) return CANAL_ERROR_MEMORY; if ( wxSEMA_TIMEOUT == pdrvObj->m_semReceiveQueue.WaitTimeout( timeout ) ) { return CANAL_ERROR_TIMEOUT; } //VSCPEVENTLIST_RECEIVE::compatibility_iterator nodeClient; pdrvObj->m_mutexReceiveQueue.Lock(); //nodeClient = pdrvObj->m_receiveQueue.GetFirst(); //vscpEvent *pLocalEvent = nodeClient->GetData(); vscpEvent *pLocalEvent = pdrvObj->m_receiveList.front(); pdrvObj->m_receiveList.pop_front(); pdrvObj->m_mutexReceiveQueue.Unlock(); if (NULL == pLocalEvent) return CANAL_ERROR_MEMORY; copyVSCPEvent( pEvent, pLocalEvent ); //pdrvObj->m_receiveQueue.DeleteNode(nodeClient); deleteVSCPevent( pLocalEvent ); return CANAL_ERROR_SUCCESS; }
void *TXWorkerThread::Entry() { eventOutQueue::compatibility_iterator node; vscpEvent *pEvent; // Must be a valid control object pointer if ( NULL == m_pCtrlObject ) return NULL; wxCommandEvent eventConnectionLost( wxVSCP_CTRL_LOST_EVENT, m_pCtrlObject->m_windowID ); /// TCP/IP Control VscpTcpIf tcpifControl; // Connect to the server with the control interface if ( !tcpifControl.doCmdOpen( m_pCtrlObject->m_ifVSCP.m_strHost, m_pCtrlObject->m_ifVSCP.m_port, m_pCtrlObject->m_ifVSCP.m_strUser, m_pCtrlObject->m_ifVSCP.m_strPassword ) ) { //::wxGetApp().logMsg ( _("VSCP TX thread - Unable to connect to server."), DAEMON_LOGMSG_CRITICAL ); m_pCtrlObject->m_errorControl = VSCP_SESSION_ERROR_UNABLE_TO_CONNECT; wxPostEvent( m_pCtrlObject->m_pWnd, eventConnectionLost ); return NULL; } // Get channel ID tcpifControl.doCmdGetChannelID( &m_pCtrlObject->m_txChannelID ); while ( !TestDestroy() && !m_pCtrlObject->m_bQuit ) { if ( wxSEMA_TIMEOUT == m_pCtrlObject->m_semOutQue.WaitTimeout( 500 ) ) continue; m_pCtrlObject->m_mutexOutQueue.Lock(); node = m_pCtrlObject->m_outQueue.GetFirst(); pEvent = node->GetData(); tcpifControl.doCmdSend( pEvent ); m_pCtrlObject->m_outQueue.DeleteNode( node ); deleteVSCPevent( pEvent ); m_pCtrlObject->m_mutexOutQueue.Unlock(); } // while // Close the interface tcpifControl.doCmdClose(); wxPostEvent( m_pCtrlObject->m_pWnd, eventConnectionLost ); return NULL; }
void *UDPReceiveThread::Entry() { unsigned long errorCode = 0; #ifdef WIN32 int nLen; #else socklen_t nLen; #endif unsigned char buf[ 1024 ]; unsigned char *p; CLIENTEVENTLIST::compatibility_iterator nodeVSCP; vscpEvent *pvscpEvent = NULL; // Must be a valid control object pointer if (NULL == m_pCtrlObject) return NULL; // We need to create a clientobject and add this object to the list CClientItem *pClientItem = new CClientItem; if (NULL == pClientItem) return NULL; // This is an active client pClientItem->m_bOpen = true; pClientItem->m_type = CLIENT_ITEM_INTERFACE_TYPE_CLIENT_INTERNAL; pClientItem->m_strDeviceName = _("Internal UDP Receive Client. Started at "); wxDateTime now = wxDateTime::Now(); pClientItem->m_strDeviceName += now.FormatISODate(); pClientItem->m_strDeviceName += _(" "); pClientItem->m_strDeviceName += now.FormatISOTime(); // Mark as UDP receive channel pClientItem->m_bUDPReceiveChannel = true; // Add the client to the Client List m_pCtrlObject->m_wxClientMutex.Lock(); m_pCtrlObject->addClient(pClientItem/*, CLIENT_ITEM_SPECIAL_ID_UDP*/); m_pCtrlObject->m_wxClientMutex.Unlock(); crcInit(); char szName[ 128 ]; struct hostent * lpLocalHostEntry; if (-1 == gethostname(szName, sizeof( szName))) { wxLogError(_("UDP Receive Thread: Failed to get hostname\n")); return NULL; } wxLogDebug(_("udpReceiceThread: Hostname: %s"), szName); lpLocalHostEntry = gethostbyname(szName); if (NULL == lpLocalHostEntry) { wxLogError(_("UDP Receive Thread: Failed to get hostaddress\n")); return NULL; } // Get the address //localaddr = (in_addr_t *)lpLocalHostEntry->h_addr_list[ 0 ]; #ifndef WIN32 /* char ac[ 80 ]; if ( gethostname( ac, sizeof( ac ) ) == -1 ) { ; } struct hostent *phe = gethostbyname( ac ); for ( int i = 0; phe->h_addr_list[i] != 0; ++i ) { struct in_addr addr; memcpy( &addr, phe->h_addr_list[i], sizeof (struct in_addr ) ); //cout << "Address " << i << ": " << inet_ntoa(addr) << endl; wxLogDebug( _("Interface address: %X\n"), addr ); } */ #endif // Get all local addresses of the local machine int idx = -1; void *pAddr; #ifdef WIN32 unsigned long localaddr[ 16 ]; // max 16 local addresses #else in_addr_t localaddr[ 16 ]; // max 16 local addresses #endif do { idx++; localaddr[ idx ] = 0; #ifdef WIN32 pAddr = lpLocalHostEntry->h_addr_list[ idx ]; if (NULL != pAddr) localaddr[ idx ] = *((unsigned long *) pAddr); #else pAddr = (in_addr_t *) lpLocalHostEntry->h_addr_list[ idx ]; if (NULL != pAddr) localaddr[ idx ] = *((in_addr_t *) pAddr); if (NULL != pAddr) wxLogTrace(_("wxTRACE_vscpd_receiveQueue"), _("udpReceiceThread: Local address: %X"), * (in_addr_t *) pAddr); #endif } while ((NULL != pAddr) && (idx < 16)); // // Create a UDP/IP datagram socket // int theSocket; theSocket = socket(AF_INET, SOCK_DGRAM, 0); if (-1 == theSocket) { return NULL; } int on = 1; // As suggested by Charles Tewiah setsockopt(theSocket, SOL_SOCKET, SO_REUSEADDR, (const char *) &on, sizeof( on)); // // Fill in the address structure // struct sockaddr_in saServer; saServer.sin_family = AF_INET; saServer.sin_addr.s_addr = INADDR_ANY; saServer.sin_port = htons(m_pCtrlObject->m_UDPPort); // For multi interface machines. // If no bind address is given the default interface is used to receive // UDP datagrams which means datagrams will be received from all interfaces. Set // to ip of interface to select a specific interface. if (0 != m_pCtrlObject->m_strUdpBindInterfaceAddress.Length()) { #if ( WIN32 && (_WIN32_WINNT<0x0600) ) saServer.sin_addr.s_addr = inet_addr(m_pCtrlObject->m_strUdpBindInterfaceAddress.ToAscii()); #else inet_pton(AF_INET, m_pCtrlObject->m_strUdpBindInterfaceAddress.ToAscii(), (void *) &saServer.sin_addr.s_addr); #endif } // // bind the name to the socket // int nRet; nRet = bind(theSocket, (struct sockaddr *) &saServer, sizeof( struct sockaddr)); if (-1 == nRet) { return NULL; } struct sockaddr_in saClient; nLen = sizeof( struct sockaddr_in); wxLogDebug(_("udpReceiceThread: Ready to Work!")); while (!TestDestroy() && !m_bQuit) { #ifdef WIN32 memset(buf, 0, sizeof( buf)); // Wait for data from the client nRet = recvfrom(theSocket, (char *) buf, sizeof(buf), 0, (LPSOCKADDR) & saClient, &nLen); if (!nRet || (nRet == SOCKET_ERROR) || (nRet < 25)) { continue; } #else bzero((uint8_t *) & saClient, sizeof( saClient)); nLen = sizeof( struct sockaddr_in); bzero((uint8_t *) buf, sizeof( buf)); // Wait for data from the client nRet = recvfrom(theSocket, buf, sizeof( buf), 0, (struct sockaddr *) &saClient, &nLen); if ((0 == nRet) || (-1 == nRet) || (nRet < 25)) { continue; } wxLogDebug(_("udpReceiveThread: Incoming event. Addr=%X"), (in_addr_t) saClient.sin_addr.s_addr); #endif // Handle received package #ifdef WIN32 // If this is a packet sent from this machine // we just disregards it bool bLocalAddress = false; idx = 0; while ((0 != localaddr[ idx ]) && (idx < 16)) { if (localaddr[ idx ] == (unsigned long) saClient.sin_addr.S_un.S_addr) { bLocalAddress = true; break; } idx++; } #else // If this is a packet sent from this machine // we just disregards it //if ( *localaddr == saClient.sin_addr.s_addr ) continue; bool bLocalAddress = false; idx = 0; while ((0 != localaddr[ idx ]) && (idx < 16)) { wxLogTrace(_("wxTRACE_vscpd_receiveQueue"), _(" Received address = %x"), (in_addr_t) saClient.sin_addr.s_addr); if (localaddr[ idx ] == (in_addr_t) saClient.sin_addr.s_addr) { bLocalAddress = true; wxLogTrace(_("wxTRACE_vscpd_receiveQueue"), _("Skipped because event has local origin ")); break; } idx++; } #endif if (bLocalAddress) continue; // From ourself get next event wxLogTrace(_("wxTRACE_vscpd_receiveQueue"), _("udpReceiveThread: It's from another machine. Grab it.")); // Check size // The size member must be low enough for the data to fit // in the package unsigned short size; p = (unsigned char *) &size; * (p + 0) = buf[ VSCP_UDP_POS_SIZE + 1 ]; * (p + 1) = buf[ VSCP_UDP_POS_SIZE + 0 ]; if ((size + 25) > nRet) { // Wrong size -> Package faulty continue; } // Calculate CRC if requested if (!(buf[ VSCP_UDP_POS_HEAD + 0 ] & VSCP_NO_CRC_CALC)) { if (!crcFast(buf, size)) continue; // Faulty CRC } vscpEvent *pEvent = new vscpEvent; if (NULL != pEvent) { pEvent->obid = pClientItem->m_clientID; // Head p = (unsigned char *) &pEvent->head; * (p + 0) = buf[ VSCP_UDP_POS_HEAD + 0 ]; // VSCP class p = (unsigned char *) &pEvent->vscp_class; * (p + 0) = buf[ VSCP_UDP_POS_CLASS + 1 ]; * (p + 1) = buf[ VSCP_UDP_POS_CLASS + 0 ]; // VSCP type p = (unsigned char *) &pEvent->vscp_type; * (p + 0) = buf[ VSCP_UDP_POS_TYPE + 1 ]; * (p + 1) = buf[ VSCP_UDP_POS_TYPE + 0 ]; // Node address p = (unsigned char *) &pEvent->GUID; memcpy(p, &buf[ VSCP_UDP_POS_GUID + 0 ], 16); // Number of valid data bytes pEvent->sizeData = size; if (pEvent->sizeData > 487) { // Can't be a VSCP package delete pEvent; continue; } // CRC p = (unsigned char *) &pEvent->crc; * (p + 0) = buf[ VSCP_UDP_POS_CRC + 1 ]; * (p + 1) = buf[ VSCP_UDP_POS_CRC + 0 ]; pEvent->pdata = NULL; if (0 != pEvent->sizeData) { // Allocate storage for data unsigned char *pDataArea = new unsigned char[ pEvent->sizeData ]; if (NULL != pDataArea) { // Data Max 487 (512- 25) bytes pEvent->pdata = pDataArea; // size = sz - command_byte - control_bytes memcpy(pEvent->pdata, &buf[ VSCP_UDP_POS_DATA ], pEvent->sizeData); } } // RX Statistics pClientItem->m_statistics.cntReceiveData += pEvent->sizeData; pClientItem->m_statistics.cntReceiveFrames++; // There must be room in the send queue if (m_pCtrlObject->m_maxItemsInClientReceiveQueue > m_pCtrlObject->m_clientOutputQueue.GetCount()) { m_pCtrlObject->m_mutexClientOutputQueue.Lock(); m_pCtrlObject->m_clientOutputQueue.Append(pEvent); m_pCtrlObject->m_semClientOutputQueue.Post(); m_pCtrlObject->m_mutexClientOutputQueue.Unlock(); } else { pClientItem->m_statistics.cntOverruns++; deleteVSCPevent(pEvent); } } } // while #ifdef WIN32 _close(theSocket); #else close(theSocket); #endif // Remove the client m_pCtrlObject->m_wxClientMutex.Lock(); m_pCtrlObject->removeClient(pClientItem); m_pCtrlObject->m_wxClientMutex.Unlock(); return NULL; }
void *UDPSendThread::Entry() { // Must have a valid pointer to the control object if (NULL == m_pCtrlObject) return NULL; // We need to create a clientobject and add this object to the list CClientItem *pClientItem = new CClientItem; if (NULL == pClientItem) return NULL; // This is an active client pClientItem->m_bOpen = true; pClientItem->m_type = CLIENT_ITEM_INTERFACE_TYPE_CLIENT_INTERNAL; pClientItem->m_strDeviceName = _("Internal UDP Transmit Client. Started at "); wxDateTime now = wxDateTime::Now(); pClientItem->m_strDeviceName += now.FormatISODate(); pClientItem->m_strDeviceName += _(" "); pClientItem->m_strDeviceName += now.FormatISOTime(); // Add the client to the Client List m_pCtrlObject->m_wxClientMutex.Lock(); m_pCtrlObject->addClient(pClientItem/*, CLIENT_ITEM_SPECIAL_ID_UDP*/); m_pCtrlObject->m_wxClientMutex.Unlock(); // Create the socket for Level II UDP datagrams sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(0); // Using the INADDR_ANY interface datagrams will be sent on the first found interface // on a machine with multiple interfaces. If the ifaddress is set to another valid // address that interface will be used instead. if (0 != m_pCtrlObject->m_strUdpInterfaceAddress.Length()) { #if ( WIN32 && (_WIN32_WINNT<0x0600) ) addr.sin_addr.s_addr = inet_addr(m_pCtrlObject->m_strUdpBindInterfaceAddress.ToAscii()); #else inet_pton(AF_INET, m_pCtrlObject->m_strUdpInterfaceAddress.ToAscii(), (void *) &addr.sin_addr.s_addr); #endif } if (-1 != (m_sendsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))) { int on = 1; setsockopt(m_sendsock, SOL_SOCKET, SO_BROADCAST, (const char*) &on, sizeof( on)); on = 1; // As suggested by Charles Tewiah setsockopt(m_sendsock, SOL_SOCKET, SO_REUSEADDR, (const char *) &on, sizeof( on)); if (1 == bind(m_sendsock, (struct sockaddr*) &addr, sizeof( addr))) { m_pCtrlObject->logMsg(_("vscpd: Faild to bind send socket. Functionality disabled."), DAEMON_LOGMSG_ERROR); #ifdef WIN32 if (NULL != m_sendsock) closesocket(m_sendsock); m_sendsock = NULL; #else if (0 != m_sendsock) close(m_sendsock); m_sendsock = 0; #endif } } else { m_pCtrlObject->logMsg(_("vscpd: Faild to create send socket. Functionality disabled."), DAEMON_LOGMSG_ERROR); #ifdef WIN32 m_sendsock = NULL; #else m_sendsock = 0; #endif } char szName[ 128 ]; #ifdef WIN32 LPHOSTENT lpLocalHostEntry; #else struct hostent *lpLocalHostEntry; #endif gethostname(szName, sizeof( szName)); lpLocalHostEntry = gethostbyname(szName); if (NULL == lpLocalHostEntry) { return NULL; } // Get all local addresses for interface int cntAddr = -1; void *pAddr; unsigned long localaddr[ 16 ]; // max 16 local addresses do { cntAddr++; localaddr[ cntAddr ] = 0; pAddr = lpLocalHostEntry->h_addr_list[ cntAddr ]; if (NULL != pAddr) localaddr[ cntAddr ] = *((unsigned long *) pAddr); } while ((NULL != pAddr) && (cntAddr < 16)); CLIENTEVENTLIST::compatibility_iterator nodeVSCP; vscpEvent *pvscpEvent = NULL; while (!TestDestroy() && !m_bQuit) { // Wait for event if (wxSEMA_TIMEOUT == pClientItem->m_semClientInputQueue.WaitTimeout(500)) continue; if (pClientItem->m_clientInputQueue.GetCount()) { pClientItem->m_mutexClientInputQueue.Lock(); nodeVSCP = pClientItem->m_clientInputQueue.GetFirst(); pvscpEvent = nodeVSCP->GetData(); // Remove event from sendqueue pClientItem->m_clientInputQueue.DeleteNode(nodeVSCP); pClientItem->m_mutexClientInputQueue.Unlock(); if ((NULL != pvscpEvent)) { sendUdpEvent(pvscpEvent); } // Delete the event deleteVSCPevent(pvscpEvent); } } // while // Remove the client m_pCtrlObject->m_wxClientMutex.Lock(); m_pCtrlObject->removeClient(pClientItem); m_pCtrlObject->m_wxClientMutex.Unlock(); return NULL; }
extern "C" void WINAPI EXPORT vscp_deleteVSCPevent( vscpEvent *pEvent ) { return deleteVSCPevent( pEvent ); }
void ctrlUpdate::eventThreadMessage( wxCommandEvent &event ) { int write_pointer,checksum16; unsigned long intflash_blocksize,max_intflash_blocknumber,extflash_blocksize,max_extflash_blocknumber; int block_number; int i = event.GetInt(); int id = i & 0xFFFF; int type = (i >> 16) & 0xFFFF; CDeviceNode* pNode = m_plistNode->GetNodeByNickName(id); wxString strData = event.GetString(); vscpEvent* pVscp = new vscpEvent; getVscpDataFromString( pVscp, strData ); if(pNode != NULL) { if(event.GetExtraLong()==0) { switch(type) { case VSCP_TYPE_PROTOCOL_ACK_BOOT_LOADER: // pVscp->pdata[ 0 ] = 2; MSB internal flash block size // pVscp->pdata[ 1 ] = 2; MSB spi flash block size // pVscp->pdata[ 2 ] = 0; LSB spi flash block size // pVscp->pdata[ 3 ] = 0; LSB internal flash block size // pVscp->pdata[ 4 ] = 1; MSB internal flash number of block avalaible // pVscp->pdata[ 5 ] = 4; MSB spi flash number of block avalaible // pVscp->pdata[ 6 ] = 0; LSB spi flash number of block avalaible // pVscp->pdata[ 7 ] = 0; LSB internal flash number of block avalaible intflash_blocksize = (pVscp->pdata[0] << 8) | pVscp->pdata[3]; extflash_blocksize = (pVscp->pdata[1] << 8) | pVscp->pdata[2]; max_intflash_blocknumber = (pVscp->pdata[4] << 8) | pVscp->pdata[7]; max_extflash_blocknumber = (pVscp->pdata[5] << 8) | pVscp->pdata[6]; if((intflash_blocksize == BLOCKDATA_SIZE) && (extflash_blocksize == BLOCKDATA_SIZE) && (max_intflash_blocknumber >= (m_IntFlashBinaryLength/BLOCKDATA_SIZE))&& (max_extflash_blocknumber >= (m_ExtFlashBinaryLength/BLOCKDATA_SIZE)) ) { crcInit(); m_nTotalChecksum = 0; m_nCurrentBlockNumber = 0; m_nCurrentFlashType = INT_FLASH; // internal flash // attenzione: questo messaggio (VSCP_TYPE_PROTOCOL_ACK_BOOT_LOADER) è l'ultimo arrivato dal // programma user, ora ha preso il controllo il bootloader; è probabile che sia necessario // un delay prima di trasmettere il messaggio di "start block transfer" wxMilliSleep( 2000 );//wxMilliSleep( 500 );//wxMilliSleep( 200 ); StartBlockTransferMsg( pNode->GetNickName(), m_nCurrentBlockNumber, m_nCurrentFlashType ); } else { UpdateError(pNode); } //::wxGetApp().logMsg ( _("event ack bootloader"), DAEMON_LOGMSG_CRITICAL ); break; case VSCP_TYPE_PROTOCOL_START_BLOCK_ACK: // pVscp->pdata[0] MSB block number // pVscp->pdata[1] INTERNAL_FLASH/SPI_FLASH // pVscp->pdata[2] // pVscp->pdata[3] LSB block number if(m_nCurrentFlashType == pVscp->pdata[1]) { switch(m_nCurrentFlashType) { case INT_FLASH: DataBlockTransferMsg(); m_nChecksum = crcFast( &m_pIntFlashBinaryContent[USER_PROGRAM_ADDRESS + m_nCurrentBlockNumber*BLOCKDATA_SIZE], BLOCKDATA_SIZE );//crcFast( &m_pIntFlashBinaryContent[30208], BLOCKDATA_SIZE );//crcFast( &m_pIntFlashBinaryContent[USER_PROGRAM_ADDRESS + m_nCurrentBlockNumber*BLOCKDATA_SIZE], BLOCKDATA_SIZE ); //m_nTotalChecksum += m_nChecksum; break; case EXT_FLASH: DataBlockTransferMsg(); m_nChecksum = crcFast( &m_pExtFlashBinaryContent[m_nCurrentBlockNumber*BLOCKDATA_SIZE], BLOCKDATA_SIZE ); break; } } else { UpdateError(pNode); } //::wxGetApp().logMsg ( _("event ack data block"), DAEMON_LOGMSG_CRITICAL ); break; case VSCP_TYPE_PROTOCOL_BLOCK_DATA_ACK: // pVscp->pdata[0] = (checksum16 >> 8) & 0xFF; MSB 16 bit CRC for block // pVscp->pdata[1] = checksum16 & 0xFF; LSB 16 bit CRC for block // pVscp->pdata[2] = (write_pointer >> 8) & 0xFF; MSB of block number // pVscp->pdata[3] = 0; // pVscp->pdata[4] = 0; // pVscp->pdata[5] = write_pointer & 0xFF; LSB of block number checksum16 = (pVscp->pdata[0] << 8) | pVscp->pdata[1]; write_pointer = (pVscp->pdata[2] << 8) | pVscp->pdata[5]; if((checksum16 == m_nChecksum) && (write_pointer == m_nCurrentBlockNumber)) BlockProgramMsg( m_nCurrentBlockNumber, m_nCurrentFlashType ); else { // in questo caso di errore si ritrasmette il blocco StartBlockTransferMsg( pNode->GetNickName(), m_nCurrentBlockNumber, m_nCurrentFlashType ); //UpdateError(pNode); } //::wxGetApp().logMsg ( _("event ack data block"), DAEMON_LOGMSG_CRITICAL ); break; case VSCP_TYPE_PROTOCOL_PROGRAM_BLOCK_DATA_ACK: // pVscp->pdata[0] MSB block number // pVscp->pdata[1] INTERNAL_FLASH/SPI_FLASH // pVscp->pdata[2] // pVscp->pdata[3] LSB block number block_number = (pVscp->pdata[0] << 8) | pVscp->pdata[3]; if((block_number == m_nCurrentBlockNumber) && (pVscp->pdata[1] == m_nCurrentFlashType)) { switch(m_nCurrentFlashType) { case INT_FLASH: m_nCurrentBlockNumber++; //::wxGetApp().logMsg ( _("event PROGRAM ACK"), DAEMON_LOGMSG_CRITICAL ); m_nTotalChecksum += m_nChecksum; if(m_nCurrentBlockNumber == (int)((m_IntFlashBinaryLength - USER_PROGRAM_ADDRESS)/BLOCKDATA_SIZE)) { m_nCurrentBlockNumber = 0; m_nCurrentFlashType = EXT_FLASH; //ActivateNewImageMsg(); // DEBUG!! } //else // DEBUG!! //{// DEBUG!! // avanzamento progress control della dialog pNode->FirmwareProgressStep(); wxGetApp().Yield(); StartBlockTransferMsg( pNode->GetNickName(), m_nCurrentBlockNumber, m_nCurrentFlashType ); //}// DEBUG!! break; case EXT_FLASH: m_nCurrentBlockNumber++; if(m_nCurrentBlockNumber == (int)(m_ExtFlashBinaryLength/BLOCKDATA_SIZE)) { ActivateNewImageMsg(); } else { // avanzamento progress control della dialog pNode->FirmwareProgressStep(); wxGetApp().Yield(); StartBlockTransferMsg( pNode->GetNickName(), m_nCurrentBlockNumber, m_nCurrentFlashType ); } break; } } else { UpdateError(pNode); } //::wxGetApp().logMsg ( _("event ack program block"), DAEMON_LOGMSG_CRITICAL ); break; case VSCP_TYPE_PROTOCOL_ACTIVATENEWIMAGE_ACK: // delay per attendere che il nodo remoto abbia finito la fase di // inizializzazione altrimenti quando l'utente chiude la dialog di update // c'e' il rischio che il gestore dell' heartbeat non rilevi il nuovo stato (stato user) // del nodo wxMilliSleep( 8000 ); m_tDoneUpgrade = wxDateTime::Now(); ::wxGetApp().logMsg ( wxT("Upgrade Finished... taking: ") + (m_tDoneUpgrade - m_tStartUpgrade).Format(), DAEMON_LOGMSG_CRITICAL ); // avvisa la dialog che è finito il processo di update pNode->EndFirmwareProgress(FIRMWAREUPDATEOK); break; case VSCP_TYPE_PROTOCOL_NACK_BOOT_LOADER: UpdateError(pNode); ::wxGetApp().logMsg ( _("event NACK bootloader"), DAEMON_LOGMSG_CRITICAL ); break; case VSCP_TYPE_PROTOCOL_START_BLOCK_NACK: UpdateError(pNode); ::wxGetApp().logMsg ( _("event NACK start block"), DAEMON_LOGMSG_CRITICAL ); break; case VSCP_TYPE_PROTOCOL_BLOCK_DATA_NACK: UpdateError(pNode); ::wxGetApp().logMsg ( _("event NACK data block"), DAEMON_LOGMSG_CRITICAL ); break; case VSCP_TYPE_PROTOCOL_PROGRAM_BLOCK_DATA_NACK: UpdateError(pNode); ::wxGetApp().logMsg ( _("event NACK program block"), DAEMON_LOGMSG_CRITICAL ); break; case VSCP_TYPE_PROTOCOL_ACTIVATENEWIMAGE_NACK: UpdateError(pNode); ::wxGetApp().logMsg ( _("event NACK activate new image"), DAEMON_LOGMSG_CRITICAL ); break; } } else { UpdateError(pNode); } } deleteVSCPevent( pVscp ); }