reSIProcate/DialogUsageManager  9694
rlsServer.cxx
Go to the documentation of this file.
00001 #include "resip/stack/SipStack.hxx"
00002 #include "resip/dum/ClientAuthManager.hxx"
00003 #include "resip/dum/ClientRegistration.hxx"
00004 #include "resip/dum/ClientSubscription.hxx"
00005 #include "resip/dum/DialogUsageManager.hxx"
00006 #include "resip/dum/RegistrationHandler.hxx"
00007 #include "resip/dum/Profile.hxx"
00008 #include "resip/dum/PublicationHandler.hxx"
00009 #include "resip/dum/SubscriptionHandler.hxx"
00010 #include "resip/dum/ServerSubscription.hxx"
00011 #include "rutil/Log.hxx"
00012 #include "rutil/Logger.hxx"
00013 #include "rutil/ParseBuffer.hxx"
00014 #include "rutil/Subsystem.hxx"
00015 #include "resip/dum/AppDialogSet.hxx"
00016 #include "resip/dum/AppDialog.hxx"
00017 #include "resip/dum/AppDialogSetFactory.hxx"
00018 #include "resip/stack/Pidf.hxx"
00019 //#include "resip/stack/MultipartMixedContents.hxx"
00020 #include "resip/stack/GenericContents.hxx"
00021 
00022 
00023 #include <iostream>
00024 #include <fstream>
00025 
00026 #define RESIPROCATE_SUBSYSTEM Subsystem::TEST
00027 
00028 using namespace resip;
00029 using namespace std;
00030 
00031 class RlsRegistrationHandler : public ClientRegistrationHandler
00032 {
00033    public:
00034       virtual void onSuccess(ClientRegistrationHandle h, const SipMessage& response)
00035       {
00036           InfoLog( << "onSuccess: "  << response );
00037       }
00038 
00039       virtual void onRemoved(ClientRegistrationHandle)
00040       {
00041       }           
00042 
00043       virtual void onFailure(ClientRegistrationHandle, const SipMessage& response)
00044       {
00045           InfoLog ( << "Client::Failure: " << response );
00046           exit(-1);
00047       }
00048 };
00049 
00050 Contents* readFromFile(string filename)
00051 {
00052    ifstream is;
00053    is.open (filename.c_str(), ios::binary );
00054 
00055    if (!is.good())
00056    {
00057       exit(-1);
00058    }
00059 
00060    // get length of file:
00061    is.seekg (0, ios::end);
00062    int length = is.tellg();
00063    is.seekg (0, ios::beg);
00064 
00065    // allocate memory:
00066    char* buffer = new char[length];
00067 
00068    // read data as a block:
00069    is.read (buffer,length);
00070    
00071    Mime mimeType;
00072    
00073    ParseBuffer pb(buffer, length);
00074    pb.skipChars("Content-Type:");
00075    pb.skipWhitespace();
00076    mimeType.parse(pb);   
00077    pb.skipChars(Symbols::CRLF);   
00078    
00079    HeaderFieldValue hfv(pb.position(), length - (pb.position() - pb.start()));
00080    GenericContents orig(&hfv, mimeType);
00081    
00082    GenericContents * copy = new GenericContents(orig);
00083    delete buffer;
00084    return copy;
00085 }
00086 
00087 
00088 class RlsServerSubscriptionHandler : public ServerSubscriptionHandler
00089 {
00090   public:   
00091       class RlsSubscription
00092       {
00093          public:
00094             RlsSubscription() :
00095                currentContent(0)
00096             {
00097             }
00098 
00099             RlsSubscription(ServerSubscriptionHandle h, int pos) :
00100                handle(h),
00101                currentContent(pos)
00102             {
00103             }
00104                
00105             ServerSubscriptionHandle handle;
00106             int currentContent;            
00107       };      
00108          
00109       //first file is a full notification, no restriction on the rest
00110       RlsServerSubscriptionHandler(const vector<string> inputFiles)
00111       {
00112          for (vector<string>::const_iterator it = inputFiles.begin(); it != inputFiles.end(); it++)
00113          {
00114             mContentsList.push_back(readFromFile(*it));
00115          }
00116       }
00117 
00118       virtual void onNewSubscription(ServerSubscriptionHandle handle, const SipMessage& sub)
00119       {
00120          InfoLog ( << "onNewSubscription: " << sub.header(h_RequestLine) << "\t" << 
00121                    sub.header(h_From) << "\t" << handle->getAppDialog()->getDialogId());
00122          assert(mHandleMap.find(handle->getAppDialog()->getDialogId()) == mHandleMap.end());
00123          mHandleMap[handle->getAppDialog()->getDialogId()] = RlsSubscription(handle, 1);
00124          handle->send(handle->accept());
00125          SipMessage& notify = handle->update(mContentsList[0]);
00126          notify.header(h_Requires).push_back(Token("eventlist"));
00127          handle->send(notify);
00128       }
00129       
00130       virtual void onTerminated(ServerSubscriptionHandle sub)
00131       {
00132          InfoLog ( << "onTerminated: " << sub->getAppDialog()->getDialogId());
00133          mHandleMap.erase(sub->getAppDialog()->getDialogId());
00134       }
00135 
00136       //refresh resets to beginning
00137       virtual void onRefresh(ServerSubscriptionHandle handle, const SipMessage& sub)
00138       {
00139          DialogToHandle::iterator it = mHandleMap.find(handle->getAppDialog()->getDialogId());
00140          if (it == mHandleMap.end())
00141          {
00142             assert(0);
00143          }
00144          else
00145          {
00146             ServerSubscriptionHandle handle = it->second.handle;
00147             it->second.currentContent = 0;            
00148             SipMessage& notify = handle->update(mContentsList[it->second.currentContent++]);
00149             notify.header(h_Requires).push_back(Token("eventlist"));
00150             handle->send(notify);
00151          }
00152       }
00153       
00154       virtual bool hasDefaultExpires() const
00155       {
00156          return true;
00157       }
00158       
00159       virtual int getDefaultExpires() const
00160       {
00161          return 600;
00162       }
00163 
00164       virtual void sendNextNotify()
00165       {
00166          for (DialogToHandle::iterator it = mHandleMap.begin(); it != mHandleMap.end(); it++)
00167          {
00168             ServerSubscriptionHandle handle = it->second.handle;
00169             if (it->second.currentContent > mContentsList.size())
00170             {
00171                handle->end();
00172             }
00173             else
00174             {
00175                SipMessage& notify = handle->update(mContentsList[it->second.currentContent++]);
00176                notify.header(h_Requires).push_back(Token("eventlist"));
00177                handle->send(notify);
00178             }
00179          }
00180       }
00181       
00182       virtual ~RlsServerSubscriptionHandler()
00183       {
00184          //clean up map, contents
00185       }
00186    private:
00187       typedef map<DialogId, RlsSubscription> DialogToHandle;
00188       DialogToHandle mHandleMap;
00189       typedef vector<Contents*> ContentsList;
00190       vector<Contents*> mContentsList;
00191 };
00192    
00193 
00194 int 
00195 main (int argc, char** argv)
00196 {
00197    if (argc == 1)
00198    {
00199       cerr << "Usage: rlsServer contentsFile (SPACE contentsFile) << endl";
00200       return -1;
00201    }
00202  
00203    Log::initialize(Log::Cout, Log::Debug, argv[0]);
00204 
00205    vector<string> inputFiles;
00206    for (int i = 1; i < argc; i++)
00207    {
00208       inputFiles.push_back(string(argv[i]));
00209    }
00210 
00211    RlsServerSubscriptionHandler subServerHandler(inputFiles);
00212    
00213    NameAddr from("sip:testRlsServer@internal.xten.net");
00214    Profile profile;   
00215    profile.setDefaultFrom(from);
00216    profile.clearSupportedMethods();
00217    profile.addSupportedMethod(SUBSCRIBE);   
00218 
00219    profile.validateAcceptEnabled() = false;
00220    profile.validateContentLanguageEnabled() = false;
00221    profile.validateContentEnabled() = false;
00222 
00223    DialogUsageManager dum;
00224    dum.addTransport(UDP, 15060);
00225 //   dum.addTransport(TCP, 15060);
00226 
00227    dum.setProfile(&profile);
00228    dum.addServerSubscriptionHandler("presence", &subServerHandler);
00229 
00230    RlsRegistrationHandler regHandler;
00231    dum.setClientRegistrationHandler(&regHandler);
00232 
00233    SipMessage & regMessage = dum.makeRegistration(from);
00234    InfoLog( << regMessage << "Generated register: " << endl << regMessage );
00235    dum.send( regMessage );
00236 
00237    while (true)
00238    {
00239       FdSet fdset;
00240       dum.buildFdSet(fdset);
00241       int err = fdset.selectMilliSeconds(100);
00242       assert ( err != -1 );
00243       dum.process(fdset);
00244       
00245 //         char c;
00246 //         char str[256];
00247 //         if (!cin.eof())
00248 //         {
00249 //            c=cin.get();
00250 //            if ( c == 'n' || c == 'q') 
00251 //            {
00252 //               if (c == 'q')
00253 //               {
00254 //                  break;
00255 //               }
00256 //               else
00257 //               {
00258 //                  subServerHandler.sendNextNotify();
00259 //               }
00260 //            }
00261 //            else
00262 //            {
00263 //               cin >> str;
00264 //               cout << " You have entered [" << str << "] enter n to send the next notify or q to quit " << endl;
00265 //            }
00266 //         }
00267    }
00268    
00269    return 0;
00270 
00271 }   
00272 
00273 /* ====================================================================
00274  * The Vovida Software License, Version 1.0 
00275  * 
00276  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00277  * 
00278  * Redistribution and use in source and binary forms, with or without
00279  * modification, are permitted provided that the following conditions
00280  * are met:
00281  * 
00282  * 1. Redistributions of source code must retain the above copyright
00283  *    notice, this list of conditions and the following disclaimer.
00284  * 
00285  * 2. Redistributions in binary form must reproduce the above copyright
00286  *    notice, this list of conditions and the following disclaimer in
00287  *    the documentation and/or other materials provided with the
00288  *    distribution.
00289  * 
00290  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00291  *    and "Vovida Open Communication Application Library (VOCAL)" must
00292  *    not be used to endorse or promote products derived from this
00293  *    software without prior written permission. For written
00294  *    permission, please contact vocal@vovida.org.
00295  *
00296  * 4. Products derived from this software may not be called "VOCAL", nor
00297  *    may "VOCAL" appear in their name, without prior written
00298  *    permission of Vovida Networks, Inc.
00299  * 
00300  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00301  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00302  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00303  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00304  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00305  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00306  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00307  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00308  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00309  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00310  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00311  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00312  * DAMAGE.
00313  * 
00314  * ====================================================================
00315  * 
00316  * This software consists of voluntary contributions made by Vovida
00317  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00318  * Inc.  For more information on Vovida Networks, Inc., please see
00319  * <http://www.vovida.org/>.
00320  *
00321  */