示例#1
0
ERetVal CFile::Read ( void* _pBuffer, int _iBytes )
{
	ERetVal eRetVal = RET_OK;
		
	if (!m_pFile && !m_pPackFile)
	{
		LOG(("ERR: tried to read a file that is not open. File: '%s'", m_pszFileName));
		eRetVal = RET_ERR;
	}
		
	//....not in FILEPACK
	if (m_pFile)
	{
		int bytesRead = fread( _pBuffer, 1, _iBytes, (FILE*)m_pFile );
		if (bytesRead<_iBytes)
		{
			if (m_bLog)
				LOG(("ERR: read less bytes(%d) than expected(%d). File: '%s'", bytesRead, _iBytes, m_pszFileName));
			eRetVal = RET_ERR;
		}
	}
		
	//...in FILEPACK...
	if (m_pPackFile)
	{
		eRetVal = g_pFilePack->ReadFile( _pBuffer, _iBytes, m_pPackFile );
	}
		
	UpdateError( eRetVal );
	return eRetVal;
}
示例#2
0
bool TcpConnectionListenerClass::Listen() {
    if (listen(Socket, SOMAXCONN) == SOCKET_ERROR) {
        return UpdateError();
    }

    return true;
}
示例#3
0
bool TcpConnectionListenerClass::Bind() {
    if (bind(Socket, (sockaddr*)&Address, sizeof(Address)) == SOCKET_ERROR) {
        return UpdateError();
    }

    return true;
}
示例#4
0
ERetVal CFile::Open( const char* _pszFileName )
{
	ERetVal eRetVal = RET_OK;
		
	ASSERT( _pszFileName );

	if (_pszFileName==NULL )
	{
		eRetVal = RET_ERR;
		LOG(("ERR: NULL filename\n"));
	}
		
		
	if (eRetVal==RET_OK)
	{
		SAFE_DELETE_ARRAY( m_pszFileName );
						
		if (m_bLanguageVersions)
			m_pszFileName = BuildLanguageFileName( _pszFileName );
		else
			m_pszFileName = ALLOC_COPY_STRING( _pszFileName );
				 
		eRetVal = Open_LowLvl( m_pszFileName );
		if (eRetVal!=RET_OK)
		{
			if (m_bLog)
				LOG(("ERR: cant open the file. Maybe it does not exist.: '%s'", m_pszFileName));
		}
	}
		
	UpdateError( eRetVal );
		
	return eRetVal;
}
示例#5
0
bool TcpConnectionClass::UpdateBlocking() {
    u_long Argument = !IsBlocking;
    if (ioctlsocket(Socket, FIONBIO, &Argument) == SOCKET_ERROR) {
        return UpdateError();
    }

    return true;
}
示例#6
0
bool TcpConnectionClass::Close() {
    if (Socket) {
        if (closesocket(Socket) == SOCKET_ERROR) {
            return UpdateError();
        }
        Socket = NULL;
    }
    return true;
}
示例#7
0
ERetVal CFile::Write( const char* _pszBuffer )
{
	ERetVal eRetVal = RET_ERR;
		
	if (_pszBuffer)
		eRetVal = Write( (void*)_pszBuffer, strlen(_pszBuffer ));    
		
	UpdateError( eRetVal );
	return eRetVal;    
}    
示例#8
0
bool TcpConnectionClass::SetAddress(const char* HostName, int Port) {
    hostent* HostData;
    HostData = gethostbyname(HostName);
    if (!HostData) {
        return UpdateError();
    }

    Address.sin_port = htons(Port);
    Address.sin_addr = *(in_addr*)HostData->h_addr;

    return true;
}
示例#9
0
bool TcpConnectionClass::Open() {
    // Close socket if still opened and clear the error.
    Close();
    ClearError();

    Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (Socket == SOCKET_ERROR) {
        return UpdateError();
    }

    return UpdateBlocking();
}
示例#10
0
ERetVal CFile::OpenWrite( const char* _pszFileName )
{
	ERetVal eRetVal = RET_OK;
		
	ASSERT( _pszFileName );

	if (_pszFileName==NULL )
	{
		eRetVal = RET_ERR;
		LOG(("ERR: Nombre de fichero NULL en OpenWrite"));
	}
		
	if (eRetVal==RET_OK)
	{
		SAFE_DELETE_ARRAY( m_pszFileName );
		m_pszFileName     = ALLOC_COPY_STRING( _pszFileName );
				 
		FILE* fp = fopen( m_pszFileName, "wb" );
				
		if (!fp)  // if there is an error, assumes it is because the directory is not created, and so it tries to create all the directory chain
		{
			char szDir[ MAX_FILENAME_SIZE ];
			COPY_STRING( szDir, m_pszFileName );        
			char* psz = szDir;
			char* pszSlash = NULL;
			do
			{
				char* pszSlash = strchr( psz, '/' );
				if (pszSlash)
				{
					*pszSlash = 0;
					_mkdir( szDir );
					*pszSlash = '/';
					psz = pszSlash + 1;
				}
			} while (pszSlash!=0);
						
			fp = fopen( m_pszFileName, "wb" );  // then tries to create the file again
		}
				
		if (!fp)  // if still cant, then error
		{
			eRetVal = RET_ERR;
			if (m_bLog)
				LOG(("ERR: when trying to open the file (does not exist or cant be read): '%s'", m_pszFileName));
		}
						
		m_pFile = fp;
	}
		
	UpdateError( eRetVal );
	return eRetVal;
}
示例#11
0
int TcpConnectionClass::Receive(char* Data, int DataLen, int Flags) {
    int ReceiveResult = recv(Socket,Data,DataLen,Flags);
    if (ReceiveResult == 0) {
        return -1;
    }
    if (ReceiveResult == SOCKET_ERROR) {
        if (WSAGetLastError() == WSAEWOULDBLOCK) {
            return 0;
        } else {
            UpdateError();
            return -1;
        }
    }
    return ReceiveResult;
}
示例#12
0
int TcpConnectionListenerClass::Accept(TcpConnectionClass*& AcceptedConnection) {
    SOCKET RemoteSocket = accept(Socket, NULL, 0);
    if (RemoteSocket == SOCKET_ERROR) {
        if (WSAGetLastError() == WSAEWOULDBLOCK) {
            return 0;
        } else {
            UpdateError();
            return -1;
        }
    }

    AcceptedConnection = new TcpConnectionClass();
    AcceptedConnection->Socket = RemoteSocket;
    return 1;
}
示例#13
0
void AdaptiveSparseGrid::BuildFirstLevel() {
	AdaptiveARRAY<int>* px1 = AdaptiveCoordAllocator.NewItem(dim);
	AdaptiveARRAY<int>* px2 = AdaptiveCoordAllocator.NewItem(dim);


	px1 -> fill(1);
	px2 -> fill(0);

	//! The first level is always a single point.
	AdaptiveARRAY<double> x;
	x.redim(dim);
	x.fill(0.5);

	L = 0;

	//! For the fisrt point, we always assign it to rank 0
	if (rank == 0) {
		EvaluateFunctionAtThisPoint(&x);
		AdaptiveData* pData = AdaptiveDataAllocator.NewItem();
		AdaptiveNodeData* pNodeData = AdaptiveNodeDataAllocator.NewItem();
		pData->index = px1;
		pNodeData->index = px2;
		pNodeData->surplus = new double[TotalDof];

		for ( int i = 0; i < TotalDof; i++) {
			pNodeData->surplus[i] = surplus[i];
		}

		pData->NodeData.insert(pNodeData);
		SparseGrid.push_front(pData);
	}

	MPI_Barrier(mpiCOMM);

	//Generate New sons for each dimension
	Refine(px1, px2);

	// Compute the integration value
	if ( type == 1)
	{ UpdateError(); }

	if ( rank != 0) {
		AdaptiveCoordAllocator.DeleteItem(px1);
		AdaptiveCoordAllocator.DeleteItem(px2);
	}
}
示例#14
0
ERetVal CFile::Write ( void* _pBuffer, int _iBytes )
{
	ERetVal eRetVal = RET_OK;
		
	if (!m_pFile)
	{
		LOG(("ERR: tried to write into a file that is not open. File: '%s'", m_pszFileName));
		eRetVal = RET_ERR;
	}
		
	if (m_pFile)
	{
		int bytesWriten = fwrite( _pBuffer, 1, _iBytes, (FILE*)m_pFile );
		if (bytesWriten<_iBytes)
		{
			LOG(("ERR: writen less bytes(%d) than expected(%d). File: '%s'", bytesWriten, _iBytes, m_pszFileName));
			eRetVal = RET_ERR;
		}
	}
		
	UpdateError( eRetVal );
	return eRetVal;
}
示例#15
0
int TcpConnectionClass::Connect() {
    if (connect(Socket,(sockaddr*)&Address,sizeof(sockaddr)) == SOCKET_ERROR) {
        int Err = WSAGetLastError();
        if (Err == WSAEALREADY) {
            return 400;
        }
        else if (Err == WSAEINVAL) {
            return 401;
        }
        else if (Err == WSAEWOULDBLOCK) {
            return 402;
        }
        else if (Err == WSAEISCONN) {
            return 1;
        }
        else {
            UpdateError();
            return -1;
        }
    }

    return 1;
}
示例#16
0
void AdaptiveSparseGrid::Restart(char* filename) {
	Cleanup();

	int i, j;
	ifstream infile;

	if (rank == 0)
	{ infile.open(filename); }

	if (rank == 0) {
		if (!infile.is_open()) {
			printf("Error opening file: %s\n", filename);
			return;
		}
	}



	if (rank == 0) { printf("\nNow Loading the %s \n\n", filename); }

	int number;
	AdaptiveARRAY<int>* px1, *px2;
	AdaptiveData* pData;
	AdaptiveNodeData* pNodeData;

	AdaptiveGrid IndexSet;

	pair<set<AdaptiveData*, AdaptiveDataCompare>::iterator, bool> plt;


	if ( type == 1) {

		if (rank == 0) {
			infile >> dim;
			infile >> number;
			infile >> TotalDof;
			infile >> L;
		}

		MPI_Bcast(&dim, 1, MPI_INT, 0 , mpiCOMM);
		MPI_Bcast(&number, 1, MPI_INT, 0 , mpiCOMM);
		MPI_Bcast(&TotalDof, 1, MPI_INT, 0 , mpiCOMM);
		MPI_Bcast(&L, 1, MPI_INT, 0 , mpiCOMM);

		for (int i = 1; i <= number; i++) {

			//!First load the i index;
			px1 = AdaptiveCoordAllocator.NewItem(dim);
			int sum = 0;

			if ( rank == 0) {
				for ( j = 1 ; j <= dim; j++) {
					infile >> (*px1)(j);
					sum += (*px1)(j);
				}
			}

			MPI_Bcast(px1->pData, dim, MPI_INT, 0 , mpiCOMM);
			MPI_Bcast(&sum, 1, MPI_INT, 0 , mpiCOMM);

			//!Then load the j index;
			px2 = AdaptiveCoordAllocator.NewItem(dim);

			if ( rank == 0) {
				for ( int j = 1 ; j <= dim; j++)
				{ infile >> (*px2)(j); }
			}

			MPI_Bcast(px2->pData, dim, MPI_INT, 0 , mpiCOMM);

			//!Load the surplus
			double* surplus = new double[TotalDof];

			if ( rank == 0) {
				for ( int j = 0; j < TotalDof; j++)
				{ infile >> surplus[j]; }
			}

			MPI_Bcast(surplus, TotalDof, MPI_DOUBLE, 0 , mpiCOMM);


			if ( sum != (L + dim) ) {
				if ( (i % size) == rank) {

					pData = AdaptiveDataAllocator.NewItem();
					pData-> index = px1;

					pNodeData = AdaptiveNodeDataAllocator.NewItem();
					pNodeData->surplus = new double[TotalDof];
					pNodeData->index = px2;

					for ( int k = 0; k < TotalDof; k++)
					{ pNodeData->surplus[k] = surplus[k]; }


					//! If the multi-index i has already existed, plt.second = false
					plt = IndexSet.insert(pData);

					if ( plt.second == false ) {

						AdaptiveDataAllocator.DeleteItem(pData);
						AdaptiveCoordAllocator.DeleteItem(px1);

						(*(plt.first))->NodeData.insert(pNodeData);
					}

					//! If the multi-index i has not existed, insert the multi-index j directly
					else if (plt.second == true)
					{ pData->NodeData.insert(pNodeData); }

				} else {
					AdaptiveCoordAllocator.DeleteItem(px1);
					AdaptiveCoordAllocator.DeleteItem(px2);
				}


				delete[] surplus;
			}
		}

		if (rank == 0)
		{ infile.close(); }

		//! Insert all of the points to the sparse grid.
		SparseGrid.insert(SparseGrid.begin(), IndexSet.begin(), IndexSet.end());
		IndexSet.clear();

		UpdateError();

		ifstream infile1;

		if (rank == 0)
		{ infile1.open(filename); }

		if (rank == 0) {
			infile1 >> dim;
			infile1 >> number;
			infile1 >> TotalDof;
			infile1 >> L;
		}
示例#17
0
void AdaptiveSparseGrid::ConstructAdaptiveSparseGrid() {
	//! Define a buffer deque to store all of the intermediate information
	deque<AdaptiveData*> buffer;

	//! iterator for transverse the active index
	set<AdaptiveData*, AdaptiveDataCompare>::iterator it1;
	set<AdaptiveNodeData*, AdaptiveNodeDataCompare>::iterator it2;
	AdaptiveGrid OldIndex;

	AdaptiveData* pData ;
	AdaptiveNodeData* pNodeData;

	//! Here we still keep a copy of active index for each processor for the purpose
	//! of the easy implementation of the adaptivity

	while ( !ActiveIndex.empty() && L <= Lmax ) {
		int gnumber = NumberOfActivePoints();


		if (rank == 0 && print) {
			cout << "Now, it is in Level: " << L << endl;
			cout << "The active number of points are: " << gnumber << endl;
		}

		//Copy the ActiveIndex to an oldIndex
		OldIndex = ActiveIndex;

		ActiveIndex.clear();

		//! Define a temporary matrix to store all of the active point for parallel computation
		Matrix1<double> gpoint;
		gpoint.redim(gnumber, dim);
		double time1, time;
		time1 = MPI_Wtime();
		int row = 1;

		//! Extract the coordiante information
		for (it1 = OldIndex.begin(); it1 != OldIndex.end(); ++it1) {
			for (it2 = (*it1)->NodeData.begin(); it2 != (*it1)->NodeData.end(); ++it2) {
				for ( int i = 1; i <= dim ; i++) {
					gpoint(row, i)  = IndextoCoordinate((*(*it1)->index)(i), (*(*it2)->index)(i));
				}
				row++;
			}
		}

		// Parallel Implementation

		int node;

		AdaptiveARRAY<double> px;
		px.redim(dim);

		//! Distribute the points among the processors
		int numNodesPerProcessor = 0;

		for (int i = 0; i < gnumber; i++)
			if ( (i % size) == rank)
			{ numNodesPerProcessor++; }

		int colnumber = TotalDof * numNodesPerProcessor;
		//!Local value to store function value
		double*  local_value = new double[colnumber];
		//! An array to store the nodes which belong to this processor
		int*     mynodes = new int[numNodesPerProcessor];

		for ( int no = 1 ; no <= numNodesPerProcessor; no++) {
			node = rank + size * (no - 1) + 1;
			mynodes[no - 1] = node;

			for ( int i = 1 ; i <= dim ; i++)
			{ px(i) = gpoint(node, i); }

			EvaluateFunctionAtThisPoint(&px);

			for ( int i = 0; i < TotalDof ; i++) {
				local_value[(no - 1)*TotalDof + i]  = surplus[i] ;
			}
		}

		/**
		 * EDIT BY ARYAN
		 */
		MPI_Barrier(mpiCOMM);

		time = MPI_Wtime();

		if (rank == 0 && print ) { cout << "Parallel Calculation using " << time - time1 << endl; }

		gpoint.cleanup();

		//! Set the action before storing the surplus
		BeforeStoreSurplus();

		int index = 1;
		int cnt = 0, mynode;

		//! Extract the coordiante information
		for (it1 = OldIndex.begin(); it1 != OldIndex.end(); ++it1) {

			int number = (*it1)->NodeData.size();

			//! Define a temporary matrix to store all of the active point for parallel computation
			Matrix1<double> point;
			point.redim(number, dim);

			int row = 1;

			for (it2 = (*it1)->NodeData.begin(); it2 != (*it1)->NodeData.end(); ++it2) {
				for ( int i = 1; i <= dim ; i++) {
					point(row, i)  = IndextoCoordinate((*(*it1)->index)(i), (*(*it2)->index)(i));
				}

				row++;
			}


			//! If there are points in this processor, generate a new data to store information
			if ( numNodesPerProcessor != 0) {
				pData = AdaptiveDataAllocator.NewItem();
				pData->index = (*it1)->index;
				buffer.push_front(pData);
			}


			double* temp = new double[TotalDof * number];
			//! Calculate the hierarchical surplus
			SpInterpolateLevel(point, temp);

			//! Calculate the hierarchial surplus and generate the adaptivity information
			Array<int> local_refine; local_refine.redim(number); local_refine.fill(0);
			Array<int> global_refine; global_refine.redim(number);

			int temp_index = index;
			int temp_cnt = cnt;

			it2 = (*it1)->NodeData.begin();

			for ( int n = 1;  n <= number; n++) {

				if ( (temp_cnt != numNodesPerProcessor) && (temp_index == mynodes[temp_cnt]) ) {
					for ( int i = 0; i < TotalDof; i++) {
						local_value[temp_cnt * TotalDof + i] = surplus[i] = local_value[temp_cnt * TotalDof + i] - temp[(n - 1) * TotalDof + i];
					}

					//! Check the adaptivity criteria
					local_refine(n) = IsRefine(surplus, (*it1)->index, (*it2)->index);
					temp_cnt ++;
				}

				temp_index++;
				++it2;
			}

			//! Free space
			delete[] temp;


			int error = MPI_Allreduce(local_refine.pData, global_refine.pData, number, MPI_INT, MPI_SUM, mpiCOMM);
			//if (error) { cout << "ERORR 221 : " << error <<  "|" << rank << endl; }

			//! Free space
			local_refine.cleanup();

			it2 = (*it1)->NodeData.begin();

			// calculate herarchial surplus for each coordinate
			for ( int n = 1 ; n <= number; n++) {

				//! If this point belongs to this processor
				if ( (cnt != numNodesPerProcessor) && (index == mynodes[cnt]) ) {
					//Copy data to sparse grid
					pNodeData = (*it2);
					pNodeData->surplus = new double[TotalDof];

					for ( int i = 0; i < TotalDof; i++) {
						pNodeData->surplus[i] = local_value[cnt * TotalDof + i];
					}

					//! Refinement
					if ( global_refine(n))
					{ Refine((*it1)->index, (*it2)->index); }

					cnt ++;
					//! Insert the this nodadata to the buffer
					pData->NodeData.insert(pNodeData);
				}

				//! the point doesn't belong to this processor
				else {
					if ( global_refine(n))
					{ Refine((*it1)->index, (*it2)->index); }

					//! If this point doesn't belong to this processor, delete the point.
					AdaptiveCoordAllocator.DeleteItem((*it2)->index);
					AdaptiveNodeDataAllocator.DeleteItem(*it2);
				}

				++it2;
				index++;

			}

			//free space
			global_refine.cleanup();

			//! If there are no point for this processor, delete the data.
			if ( numNodesPerProcessor == 0) {
				AdaptiveCoordAllocator.DeleteItem((*it1)->index);
				AdaptiveDataAllocator.DeleteItem(*it1);
			}
		}// End for

		//free space
		delete[] local_value;
		delete[] mynodes;

		/**
		* EDIT BY ARYAN
		*/
		MPI_Barrier(mpiCOMM);

		time1 = MPI_Wtime();

		if (rank == 0 && print) { cout << "Surplus  Calculation using " << time1 - time << endl; }

		//! Insert all of the active points to the adaptive spare grid.
		SparseGrid.insert(SparseGrid.begin(), buffer.begin(), buffer.end());

		if ( type == 1)
		{ UpdateError(); }

		//free space
		buffer.clear();
		OldIndex.clear();
		L += 1;

		//! Set the action before storing the surplus
		{ AfterStoreSurplus(); }
	}//End for
}
示例#18
0
bool TcpConnectionClass::Send(const char* Data, int DataLen) {
    if (send(Socket,Data,DataLen, 0) != DataLen) return UpdateError();
    return true;
}
示例#19
0
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 );
}