00001 // 00002 // Copyright (C) 2008 Irene Ruengeler 00003 // 00004 // This program is free software; you can redistribute it and/or 00005 // modify it under the terms of the GNU General Public License 00006 // as published by the Free Software Foundation; either version 2 00007 // of the License, or (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this program; if not, see <http://www.gnu.org/licenses/>. 00016 // 00017 00018 00019 /************************************************************ 00020 00021 To add new streamSchedulers 00022 - the appropriate functions have to be implemented, preferably 00023 in this file. 00024 - in SCTPAssociation.h an entry has to be added to 00025 enum SCTPStreamSchedulers. 00026 - in SCTPAssociationBase.cc in the contructor for SCTPAssociation 00027 the new functions have to be assigned. Compare the entries 00028 for ROUND_ROBIN. 00029 00030 00031 ************************************************************/ 00032 00033 #include "SCTPAssociation.h" 00034 #include <list> 00035 #include <math.h> 00036 00037 void SCTPAssociation::initStreams(uint32 inStreams, uint32 outStreams) 00038 { 00039 uint32 i; 00040 00041 sctpEV3<<"initStreams instreams="<<inStreams<<" outstream="<<outStreams<<"\n"; 00042 if (receiveStreams.size()==0 && sendStreams.size()==0) 00043 { 00044 for (i=0; i<inStreams; i++) 00045 { 00046 SCTPReceiveStream* rcvStream = new SCTPReceiveStream(); 00047 00048 this->receiveStreams[i]=rcvStream; 00049 rcvStream->setStreamId(i); 00050 this->state->numMsgsReq[i]=0; 00051 } 00052 for (i=0; i<outStreams; i++) 00053 { 00054 SCTPSendStream* sendStream = new SCTPSendStream(i); 00055 this->sendStreams[i]=sendStream; 00056 sendStream->setStreamId(i); 00057 } 00058 } 00059 } 00060 00061 00062 int32 SCTPAssociation::streamScheduler(bool peek) //peek indicates that no data is sent, but we just want to peek 00063 { 00064 int32 sid, testsid; 00065 00066 sctpEV3<<"Stream Scheduler: RoundRobin\n"; 00067 00068 sid = -1; 00069 00070 if ((state->ssLastDataChunkSizeSet == false || state->ssNextStream == false) && 00071 (sendStreams.find(state->lastStreamScheduled)->second->getUnorderedStreamQ()->length() > 0 || 00072 sendStreams.find(state->lastStreamScheduled)->second->getStreamQ()->length() > 0)) 00073 { 00074 sid = state->lastStreamScheduled; 00075 sctpEV3<<"Stream Scheduler: again sid " << sid << ".\n"; 00076 state->ssNextStream = true; 00077 } 00078 else 00079 { 00080 testsid = state->lastStreamScheduled; 00081 00082 do { 00083 testsid = (testsid + 1) % outboundStreams; 00084 00085 if (sendStreams.find(testsid)->second->getUnorderedStreamQ()->length() > 0 || 00086 sendStreams.find(testsid)->second->getStreamQ()->length() > 0) 00087 { 00088 sid = testsid; 00089 sctpEV3<<"Stream Scheduler: chose sid " << sid << ".\n"; 00090 00091 if (!peek) 00092 state->lastStreamScheduled = sid; 00093 } 00094 } while (sid == -1 && testsid != (int32) state->lastStreamScheduled); 00095 00096 } 00097 00098 sctpEV3<<"streamScheduler sid="<<sid<<" lastStream="<<state->lastStreamScheduled<<" outboundStreams="<<outboundStreams<<" next="<<state->ssNextStream<<"\n"; 00099 00100 state->ssLastDataChunkSizeSet = false; 00101 00102 return sid; 00103 } 00104 00105 00106 int32 SCTPAssociation::numUsableStreams(void) 00107 { 00108 int32 count=0; 00109 00110 for (SCTPSendStreamMap::iterator iter=sendStreams.begin(); iter!=sendStreams.end(); iter++) 00111 if (iter->second->getStreamQ()->length()>0 || iter->second->getUnorderedStreamQ()->length()>0) 00112 { 00113 count++; 00114 } 00115 return count; 00116 }