All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.jiac.micro.sunspot.aodv.MessageFragments Maven / Gradle / Ivy

/*
 * MicroJIAC - A Lightweight Agent Framework
 * This file is part of MicroJIAC SunSPOT-Extensions.
 *
 * Copyright (c) 2007-2011 DAI-Labor, Technische Universität Berlin
 *
 * This library includes software developed at DAI-Labor, Technische
 * Universität Berlin (http://www.dai-labor.de)
 *
 * This library is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library.  If not, see .
 */

/*
 * $Id$ 
 */
package de.jiac.micro.sunspot.aodv;

import java.io.IOException;

import com.sun.spot.peripheral.radio.IncomingData;
import com.sun.squawk.util.IntHashtable;

/**
 * @author Marcel Patzlaff
 * @version $Revision:$
 */
class MessageFragments {
    private final static long MAX_WAIT= 2000;
    
    final MessageID mid;
    private final IntHashtable _sortedFragments;
    
    private int _seqToRead;
    private boolean _lastRead= false;
    
    MessageFragments(int messageNum, int source) {
        mid= new MessageID(messageNum, source);
        _seqToRead= 1;
        _sortedFragments= new IntHashtable();
    }
    
    public void newFragment(IncomingData incoming) {
        int seq= incoming.payload[ProtocolManager.SEQ_OFFSET] & 0xFF;
//System.out.println(" ::MF:: " + seq + " received (" + incoming.payload.length + ") from " + mid.toString());
        
        synchronized (_sortedFragments) {
            if(_sortedFragments.put(seq, incoming) != null) {
                System.err.println("multiple data segment " + seq);
            }
            
            if(_seqToRead == seq) {
                _sortedFragments.notify();
            }
        }
    }
    
    public int readFragment(byte[] buffer) throws IOException {
        IncomingData incoming;
        
        synchronized (_sortedFragments) {
            if(_lastRead) {
                return -1;
            }
            
            long deadline= System.currentTimeMillis() + MAX_WAIT;
            while(!_sortedFragments.containsKey(_seqToRead)) {
                long toWait= deadline - System.currentTimeMillis();
                if(toWait <= 0) {
                    throw new IOException("waiting for segment " + _seqToRead + " timed out");
                }
                
                try {
                    _sortedFragments.wait(MAX_WAIT);
                } catch (InterruptedException e) {
                    throw new IOException("operation was interrupted");
                }
            }
            
            incoming= (IncomingData) _sortedFragments.remove(_seqToRead);
            _lastRead= incoming.payload[ProtocolManager.CTRL_OFFSET] == 1;
//System.out.println(" ::MF:: segment " + _seqToRead + " read (last = " + _lastRead + ")");
            _seqToRead= (_seqToRead + 1) % 256;
        }
        
        int numBytes= incoming.payload.length - ProtocolManager.DATA_OFFSET;
        
        System.arraycopy(incoming.payload, ProtocolManager.DATA_OFFSET, buffer, 0, numBytes);

        return numBytes;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy