]> sjero.net Git - linphone/blob - p2pproxy/src/org/linphone/p2pproxy/core/P2pProxyMain.java
remove mediastreamer2 and add it as a submodule instead.
[linphone] / p2pproxy / src / org / linphone / p2pproxy / core / P2pProxyMain.java
1 /*
2 p2pproxy Copyright (C) 2007  Jehan Monnier ()
3
4 P2pProxyMain.java - main class.
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 */
20 package org.linphone.p2pproxy.core;
21
22
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.FileNotFoundException;
26 import java.io.FileOutputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29
30 import java.lang.management.ManagementFactory;
31 import java.util.InvalidPropertiesFormatException;
32 import java.util.Properties;
33 import java.util.concurrent.Callable;
34 import java.util.concurrent.Future;
35
36 import javax.management.ObjectName;
37
38 import net.jxta.exception.JxtaException;
39 import org.apache.log4j.Logger;
40 import org.apache.log4j.PropertyConfigurator;
41 import org.linphone.p2pproxy.api.P2pProxyException;
42 import org.linphone.p2pproxy.api.P2pProxyManagement;
43 import org.linphone.p2pproxy.api.P2pProxyNotReadyException;
44 import org.linphone.p2pproxy.api.P2pProxyResourceManagement;
45 import org.linphone.p2pproxy.api.P2pProxyUserAlreadyExistException;
46 import org.linphone.p2pproxy.core.media.MediaResourceService;
47 import org.linphone.p2pproxy.core.sipproxy.SipProxyRegistrar;
48 import org.linphone.p2pproxy.core.utils.Excecutor;
49 import org.zoolu.sip.provider.SipStack;
50 import org.linphone.p2pproxy.launcher.P2pProxylauncherConstants;
51
52 public class P2pProxyMain  implements P2pProxyMainMBean {
53    private  static Logger mLog = null;
54    private  static JxtaNetworkManager mJxtaNetworkManager;
55    private  static ServiceProvider mServiceProvider;
56    private  static P2pProxyManagement mP2pProxyManagement;
57    private  static SipProxyRegistrar mSipAndPipeListener;
58    private static P2pProxyAccountManagementMBean mP2pProxyAccountManagement;
59    private static P2pProxyResourceManagement mP2pProxySipProxyRegistrarManagement;
60    public final static String ACCOUNT_MGR_MBEAN_NAME="org.linphone.p2proxy:type=account-manager";
61    public final static String PROXY_REG_MBEAN_NAME="org.linphone.p2proxy:type=proxy-registrar";
62    public final static String MAIN_MBEAN_NAME="org.linphone.p2proxy:type=main";
63    private static P2pProxyMain mP2pProxyMain = new P2pProxyMain();
64    private static Configurator mConfigurator;
65    private static String mConfigHomeDir;
66    static private boolean mExit = false;
67    static private boolean isReady = false;
68    
69    
70    
71    static {
72 //      System.setProperty("com.sun.management.jmxremote", "true");
73 //      System.setProperty("com.sun.management.jmxremote.port", "6789");
74 //      System.setProperty("com.sun.management.jmxremote.authenticate", "false");
75 //      System.setProperty("com.sun.management.jmxremote.ssl", "false");
76    }
77
78    /**
79     * @param args
80     * @throws P2pProxyException 
81     * @throws InterruptedException 
82     * @throws JxtaException 
83     * @throws IOException 
84     * @throws FileNotFoundException 
85     * @throws InvalidPropertiesFormatException 
86     */
87    public static void main(String[] args) {
88            try {
89                    mConfigHomeDir=System.getProperty("user.home")+"/.p2pproxy";
90                    int lsipPort=5040;
91                    int lMediaPort=MediaResourceService.AUDIO_VIDEO_LOCAL_PORT_DEFAULT_VALUE;
92                    int lP2pPort = 9701;
93                    JxtaNetworkManager.Mode lMode = JxtaNetworkManager.Mode.auto;
94                    // setup logging
95
96                    // get config dire first
97                    for (int i=0; i < args.length; i=i+2) {  
98                            String argument = args[i];
99                            if (argument.equals("-jxta")) {
100                                    mConfigHomeDir = args[i + 1];
101                                    File lFile = new File(mConfigHomeDir);
102                                    if (lFile.exists() == false) lFile.mkdir();
103                                  
104                                    System.out.println("mConfigHomeDir detected[" + mConfigHomeDir + "]");
105                            } 
106                    }
107                    System.setProperty("org.linphone.p2pproxy.home", mConfigHomeDir);
108                   
109                    
110                    System.setProperty("net.jxta.logging.Logging", "FINEST");
111                    System.setProperty("net.jxta.level", "FINEST");
112                    
113                    mP2pProxyMain.loadTraceConfigFile();
114                    
115                    
116                    
117                    mLog.info("p2pproxy initilizing...");
118
119                    File lPropertyFile =  new File(mConfigHomeDir+"/p2pproxy.properties.xml");
120                    mConfigurator = new Configurator(lPropertyFile);
121                    try {
122                            ObjectName lObjectName = new ObjectName(MAIN_MBEAN_NAME);
123                            ManagementFactory.getPlatformMBeanServer().registerMBean(mP2pProxyMain,lObjectName);
124
125
126                    } catch (Exception e) {
127                            mLog.warn("cannot register MBean",e);
128                    }         
129         
130                    // get other params
131                    for (int i=0; i < args.length; i=i+2) {  
132                            String argument = args[i];
133                            if (argument.equals("-jxta") || argument.equals("-home")) {
134                                    mConfigHomeDir = args[i + 1];
135                                    //nop
136                            } else if (argument.equals("-sip")) {
137                                    lsipPort = Integer.parseInt(args[i + 1]);
138                                    System.out.println("sipPort detected[" + lsipPort + "]");
139                                    mConfigurator.setProperty(SipProxyRegistrar.REGISTRAR_PORT, Integer.toString(lsipPort));
140                            } else if (argument.equals("-media")) {
141                   lMediaPort = Integer.parseInt(args[i + 1]);
142                   System.out.println("media detected[" + lMediaPort + "]");
143                   mConfigurator.setProperty(MediaResourceService.AUDIO_VIDEO_LOCAL_PORT, Integer.toString(lMediaPort));
144               } else if (argument.equals("-p2p")) {
145                   lP2pPort = Integer.parseInt(args[i + 1]);
146                   System.out.println("p2p port detected[" + lP2pPort + "]");
147                   mConfigurator.setProperty(JxtaNetworkManager.TCP_LISTENING_PORT, Integer.toString(lP2pPort));
148               } else if (argument.equals("-relay")) {
149                                    lMode = JxtaNetworkManager.Mode.relay;
150                                    mConfigurator.setProperty(JxtaNetworkManager.MODE, lMode.name());
151                                    System.out.println("relay mode detected");
152                                    i--;
153                            } else if (argument.equals("-edge-only")) {
154                                    lMode = JxtaNetworkManager.Mode.edge;
155                                    mConfigurator.setProperty(JxtaNetworkManager.MODE, lMode.name());
156                                    System.out.println("edge only mode detected");
157                                    i--;
158                            }else if (argument.equals("-seeding-server")) {
159                                    lMode = JxtaNetworkManager.Mode.seeding_server;
160                                    mConfigurator.setProperty(JxtaNetworkManager.MODE, lMode.name());
161                                    System.out.println("seeding-server  detected");
162                                    i--;
163                            } else if (argument.equals("-auto-config")) {
164                                    lMode = JxtaNetworkManager.Mode.auto;
165                                    mConfigurator.setProperty(JxtaNetworkManager.MODE, lMode.name());
166                                    System.out.println("auto-mode mode detected");
167                                    i--;
168                            }  else if (argument.equals("-seeding-rdv")) {
169                                    mConfigurator.setProperty(JxtaNetworkManager.SEEDING_RDV, args[i + 1]);
170                                    System.out.println("seeding rdv detected[" + args[i + 1] + "]");
171                            }
172                            else if (argument.equals("-seeding-relay")) {
173                                    mConfigurator.setProperty(JxtaNetworkManager.SEEDING_RELAY, args[i + 1]);
174                                    System.out.println("seeding relay detected[" + args[i + 1] + "]");
175                            }  else if (argument.equals("-seeding")) {
176                                    mConfigurator.setProperty(JxtaNetworkManager.SEEDING_RDV, args[i + 1]);
177                                    mConfigurator.setProperty(JxtaNetworkManager.SEEDING_RELAY, args[i + 1]);
178                                    System.out.println("seeding  detected[" + args[i + 1] + "]");
179                            }
180                            else if (argument.equals("-public-address")) {
181                                    mConfigurator.setProperty(JxtaNetworkManager.HTTP_LISTENING_PUBLIC_ADDRESS,args[i + 1]+":9700");
182                                    mConfigurator.setProperty(JxtaNetworkManager.TCP_LISTENING_PUBLIC_ADDRESS,args[i + 1]+":"+lP2pPort);
183                    mConfigurator.setProperty(MediaResourceService.AUDIO_VIDEO_PUBLIC_URI,"udp://"+args[i + 1]+":"+lMediaPort);
184                    mConfigurator.setProperty(SipProxyRegistrar.REGISTRAR_PUBLIC_ADDRESS,args[i + 1]);
185                    System.out.println("public address detected[" + args[i + 1] + "]");
186                            }            
187                            else
188                            {
189                                    System.out.println("Invalid option: " + args[i]);
190                                    usage();
191                                    System.exit(1);
192                            }
193                    }
194
195                    File lJxtaDirectory = new File (mConfigHomeDir);
196                    if (lJxtaDirectory.exists() == false) lJxtaDirectory.mkdir();
197
198
199                    switch (lMode) {
200                    case edge:
201                            startEdge(mConfigurator,lJxtaDirectory);
202                            break;
203                    case relay:
204                            startRelay(mConfigurator,lJxtaDirectory);
205                            break;
206                    case seeding_server:
207                            startSeeding(mConfigurator,lJxtaDirectory);
208                            break; 
209                    case auto:
210                            //1 start edge 
211                            startEdge(mConfigurator,lJxtaDirectory);
212                            // check if peer mode required
213                            if (mP2pProxyManagement.shouldIBehaveAsAnRdv() == true) {
214                                    String lPublicAddress = mP2pProxyManagement.getPublicIpAddress().getHostAddress();
215                                    mConfigurator.setProperty(JxtaNetworkManager.HTTP_LISTENING_PUBLIC_ADDRESS, lPublicAddress+":9700");
216                                    mConfigurator.setProperty(JxtaNetworkManager.TCP_LISTENING_PUBLIC_ADDRESS, lPublicAddress+":9701");
217                                    mServiceProvider.stop();
218                                    mJxtaNetworkManager.stop();
219                                    startRelay(mConfigurator,lJxtaDirectory);
220                                    mJxtaNetworkManager.getPeerGroup().getRendezVousService().setAutoStart(true);
221                            }
222                            break;
223                    default:
224                            mLog.fatal("unsupported mode ["+lMode+"]");
225                    System.exit(1);
226
227                    }
228
229
230                    //set management
231                    try {
232                            ObjectName lObjectName = new ObjectName(ACCOUNT_MGR_MBEAN_NAME);
233                            ManagementFactory.getPlatformMBeanServer().registerMBean(mP2pProxyAccountManagement,lObjectName);
234                    } catch (Exception e) {
235                            mLog.warn("cannot register MBean",e);
236                    }
237
238
239                    mLog.warn("p2pproxy initilized");
240                    isReady = true;
241                    while (mExit == false) {
242                            Thread.sleep(1000);
243                    }
244                    if (mServiceProvider!= null) mServiceProvider.stop();
245                    if (mServiceProvider!= null) mServiceProvider.stop();
246                    if (mSipAndPipeListener!= null) mSipAndPipeListener.stop();
247                    if (mJxtaNetworkManager != null) mJxtaNetworkManager.stop();
248                    mLog.info("p2pproxy stopped");
249                    return;
250                    
251            } catch (Exception e) {
252                    mLog.fatal("error",e);
253                    System.exit(1);
254            }
255    }
256    private static void startEdge(Configurator aProperties,File aConfigDir) throws Exception{
257       // setup jxta
258       mJxtaNetworkManager = new JxtaNetworkManager(aProperties,aConfigDir);
259       mServiceProvider = new EdgePeerServiceManager(aProperties, mJxtaNetworkManager);
260       mP2pProxyManagement = (P2pProxyManagement) mServiceProvider;
261       mP2pProxySipProxyRegistrarManagement = (P2pProxyResourceManagement) mServiceProvider;
262            //setup account manager
263            mP2pProxyAccountManagement = new P2pProxyAccountManagement(mJxtaNetworkManager);
264       mServiceProvider.start(3000L);
265    }
266
267    private static void startRelay(Configurator aProperties,File aConfigDir) throws Exception{
268       // setup jxta
269       mJxtaNetworkManager = new JxtaNetworkManager(aProperties,aConfigDir);
270       mServiceProvider = new SuperPeerServiceManager(aProperties, mJxtaNetworkManager);
271       mP2pProxyManagement = (P2pProxyManagement) mServiceProvider;
272       mP2pProxySipProxyRegistrarManagement = (P2pProxyResourceManagement) mServiceProvider;
273       mServiceProvider.start(3000L);
274            //setup account manager
275            mP2pProxyAccountManagement = new P2pProxyAccountManagement(mJxtaNetworkManager);
276 //    setup sip provider
277            SipStack.log_path = mConfigHomeDir+"/logs";
278            mSipAndPipeListener = new SipProxyRegistrar(mConfigurator,mJxtaNetworkManager,mP2pProxyAccountManagement);
279            //set management
280            try {
281                    ObjectName lObjectName  = new ObjectName(PROXY_REG_MBEAN_NAME);
282                    ManagementFactory.getPlatformMBeanServer().registerMBean(mSipAndPipeListener,lObjectName);
283
284            } catch (Exception e) {
285                    mLog.warn("cannot register MBean",e);
286            }
287    }
288    private static void startSeeding(Configurator aProperties,File aConfigDir) throws Exception{
289       // setup jxta
290       mJxtaNetworkManager = new JxtaNetworkManager(aProperties,aConfigDir);
291       mServiceProvider = new SeedingPeerServiceManager(aProperties, mJxtaNetworkManager,true);
292       mP2pProxyManagement = null;
293       mP2pProxySipProxyRegistrarManagement = (P2pProxyResourceManagement) mServiceProvider;
294       mServiceProvider.start(3000L);
295            //setup account manager
296            mP2pProxyAccountManagement = new P2pProxyAccountManagement(mJxtaNetworkManager);
297            //    setup sip provider
298            SipStack.log_path = mConfigHomeDir+"/logs";
299            mSipAndPipeListener = new SipProxyRegistrar(mConfigurator,mJxtaNetworkManager,mP2pProxyAccountManagement);
300            //set management
301            try {
302                    ObjectName lObjectName  = new ObjectName(PROXY_REG_MBEAN_NAME);
303                    ManagementFactory.getPlatformMBeanServer().registerMBean(mSipAndPipeListener,lObjectName);
304
305            } catch (Exception e) {
306                    mLog.warn("cannot register MBean",e);
307            }
308    }   
309    private static void usage() {
310       System.out.println("p2pproxy");
311       System.out.println("-home : directory where configuration/cache is located  (including jxta cache.default is $HOME/.p2pproxy");
312       System.out.println("-sip : udp proxy port, default 5060");
313       System.out.println("-media : udp relay/stun port, default 16000");
314       System.out.println("-p2p : p2p tcp port, default 9701");
315       System.out.println("-relay : super peer mode");
316       System.out.println("-edge-only : edge mode");
317       System.out.println("-seeding-server : seeding server mode");
318       System.out.println("-auto-config : automatically choose edge or relay (default mode)");
319       System.out.println("-seeding : list of boostrap rdv separated by | (ex tcp://127.0.0.1:9701|http://127.0.0.2:9700)");
320       System.out.println("-public-address : ip as exported to peers (ex myPublicAddress.no-ip.org)");
321    }
322   
323 public void loadTraceConfigFile() throws P2pProxyException {
324    staticLoadTraceConfigFile();
325    }
326 public  static void staticLoadTraceConfigFile()  throws P2pProxyException {
327    try {
328            InputStream lLog4jStream = null;
329            String lSearchDir;
330       //search build dir
331       lSearchDir = System.getProperty("org.linphone.p2pproxy.build.dir");
332       File lFile = new File(lSearchDir+"/log4j.properties");
333       if (lFile.exists() == false) {
334          lSearchDir = mConfigHomeDir;
335          lFile = new File(lSearchDir+"/log4j.properties");
336          if (lFile.exists() == false) {
337             lSearchDir=".";
338             lFile = new File(lSearchDir+"/log4j.properties");
339             if (lFile.exists() == false) {
340                 lLog4jStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("log4j.properties");
341                 
342             }
343          }
344       }
345       if (lLog4jStream == null) {
346           lLog4jStream = new FileInputStream(lFile);
347       }
348       Properties llog4Properties = new Properties();
349       llog4Properties.load(lLog4jStream);
350       PropertyConfigurator.configure(llog4Properties);
351       mLog = Logger.getLogger(P2pProxyMain.class);
352       // read java.util.logging properties 
353
354       llog4Properties.setProperty("java.util.logging.FileHandler.pattern",System.getProperty("org.linphone.p2pproxy.home")+"/logs/p2pproxy.log");
355       File lLogConfigFile = new File(mConfigHomeDir.concat("log4j.properties")+".tmp");
356       if (lLogConfigFile.exists() == false) {
357           lLogConfigFile.createNewFile();
358       }
359       llog4Properties.store(new FileOutputStream(lLogConfigFile), "tmp");
360       System.setProperty("java.util.logging.config.file",lLogConfigFile.getAbsolutePath());
361       java.util.logging.LogManager.getLogManager().readConfiguration();
362    } catch (Exception e) {
363       throw new P2pProxyException("enable to load traces",e);
364    }
365 }
366 private static boolean isReadyNoThrow() {
367         try {
368                 isReady();
369                 return true;
370         } catch (P2pProxyNotReadyException e) {
371                 return false;
372         }
373 }
374 private static void isReady() throws P2pProxyNotReadyException {
375     try {
376       if ((isReady == true && mJxtaNetworkManager.isConnectedToRendezVous(0) == true) 
377           || 
378           (isReady == true && mJxtaNetworkManager.getPeerGroup().getRendezVousService().isRendezVous())) {
379          //nop connected
380       } else {
381           if (mJxtaNetworkManager != null ) {
382                   throw new P2pProxyNotReadyException("not connected to any rdv: status ["+mJxtaNetworkManager.getPeerGroup().getRendezVousService().getRendezVousStatus()+"]");
383           } else {
384                   throw new P2pProxyNotReadyException("initializing");
385           }
386       }
387    } catch (InterruptedException e) {
388       throw new P2pProxyNotReadyException(e);
389    }
390 }
391 /* p2pproxy.h implementation*/
392 private static int excecuteAction(Future<Integer> aResult, Class<? extends Callable<Integer>> classTaskName) {
393         try {
394                 if (aResult.isDone() == false)  {
395                         return P2pProxylauncherConstants.P2PPROXY_EWOULDBLOCK;
396                 } else if (aResult == null) {
397                         createAccountResult = Excecutor.pool.submit(classTaskName.newInstance());
398                 } else  {
399                         Future<Integer> lResult = createAccountResult;
400                         createAccountResult = null;
401                         return lResult.get();
402                 }
403                 return P2pProxylauncherConstants.P2PPROXY_ERROR;
404         } catch (Exception e) {
405                 return P2pProxylauncherConstants.P2PPROXY_ERROR;
406         }     
407 }
408
409 static Future<Integer> createAccountResult = null;
410 public synchronized static int createAccount(final String aUserName) {
411         class CreateAcountTask implements Callable<Integer> {
412                 public Integer call() throws Exception {
413                         try {
414                                 mP2pProxyAccountManagement.createAccount(aUserName);
415                         } catch (P2pProxyUserAlreadyExistException e) {
416                                 return P2pProxylauncherConstants.P2PPROXY_ACCOUNTMGT_USER_EXIST;
417                         } catch (P2pProxyException e) {
418                                 return P2pProxylauncherConstants.P2PPROXY_ERROR;
419                         }
420                         return P2pProxylauncherConstants.P2PPROXY_NO_ERROR;
421                 }
422         };
423         return excecuteAction(createAccountResult,CreateAcountTask.class);
424
425
426 static Future<Integer> deleteAccountResult = null;
427 public static int deleteAccount(final String aUserName)  {
428         class DeleteAccountTask implements Callable<Integer> {
429
430                 public Integer call() throws Exception {
431                         mP2pProxyAccountManagement.deleteAccount(aUserName);
432                         return P2pProxylauncherConstants.P2PPROXY_NO_ERROR;
433                 }
434
435         };
436         return excecuteAction(deleteAccountResult,DeleteAccountTask.class);
437 }
438
439 static Future<Integer> isValidAccountResult = null;
440 public static int isValidAccount(final String aUserName){
441         class IsValidAccountResultTask implements Callable<Integer> {
442
443                 public Integer call() throws Exception {
444                       if (mP2pProxyAccountManagement.isValidAccount(aUserName)) {
445                           return P2pProxylauncherConstants.P2PPROXY_ACCOUNTMGT_USER_EXIST;
446                        } else {
447                           return P2pProxylauncherConstants.P2PPROXY_ACCOUNTMGT_USER_NOT_EXIST;
448                        }
449                 }
450
451         };
452         return excecuteAction(isValidAccountResult,IsValidAccountResultTask.class);
453 }
454
455 static Future<Integer> lookupSipProxyUriResult = null;
456 public static String lookupSipProxyUri(final String aDomaine) {
457    try {
458       isReady();
459       String[] lProxies = mP2pProxySipProxyRegistrarManagement.lookupSipProxiesUri(aDomaine);
460       if (lProxies.length != 0) {
461           return lProxies[0];
462       } else {
463           return null;
464       }
465    } catch (Exception e) {
466       return null;
467    } 
468 }
469
470 public static String[] lookupSipProxiesUri(String aDomaine) {
471            try {
472               isReady();
473               return mP2pProxySipProxyRegistrarManagement.lookupSipProxiesUri(aDomaine);
474            } catch (Exception e) {
475               return null;
476            } 
477         }
478
479 public static String[] lookupMediaServerAddress(String aDomaine) {
480    try {
481       isReady();
482       return mP2pProxySipProxyRegistrarManagement.getMediaServerList();
483    } catch (Exception e) {
484            mLog.error("cannot find media resource",e);
485            return null;
486    } 
487 }
488
489 public static int getState() {
490    try {
491       isReady();
492       return P2pProxylauncherConstants.P2PPROXY_CONNECTED;
493    } catch (P2pProxyException e) {
494       //if (mLog != null) mLog.info("cannot get state",e);
495       return P2pProxylauncherConstants.P2PPROXY_NOT_CONNECTED;
496    }   
497 }
498 public static int revokeSipProxy(String aProxy) {
499    try {
500       isReady();
501       mP2pProxySipProxyRegistrarManagement.revokeSipProxy(aProxy);
502       return P2pProxylauncherConstants.P2PPROXY_NO_ERROR;
503    } catch (P2pProxyException e) {
504       return P2pProxylauncherConstants.P2PPROXY_NOT_CONNECTED;
505    }   
506 }
507 public static int revokeMediaServer(String aServer) {
508            try {
509               isReady();
510               mP2pProxySipProxyRegistrarManagement.revokeMediaServer(aServer);
511               return P2pProxylauncherConstants.P2PPROXY_NO_ERROR;
512            } catch (P2pProxyException e) {
513               return P2pProxylauncherConstants.P2PPROXY_NOT_CONNECTED;
514            }   
515         }
516 public static void stop() {
517    mExit = true;
518   
519 }
520 }