Asterisk PBX Integration Zimlet

Interested in talking about Mash-up's? This is the place.
chlauber
Advanced member
Advanced member
Posts: 71
Joined: Fri Sep 12, 2014 11:41 pm

Asterisk PBX Integration Zimlet

Postby chlauber » Thu Oct 16, 2008 8:22 am

Hi all.

I started programming an asterisk zimlet that uses asterisk manager interface AMI instead of SIP protocol like the already existing Zimlet.

Thanks to Asterisk-Java I was able to easily interface with AMI in jsp.

Main purpose is to dial (originate). I also added SMS functionality that uses Asterik SMS() application. For now every originate does a separate login to AMI, send action and then logs out. Don't now if this can cause troubles in big installations.
Finally i have something working, but there are still some problems.
1) Internationalization:

I was unable to get messages.properties files to work. Already check the Forum and Zimlets Whitepaper, but still no luck.

So for now everything is hardcoded in English.
2) SMS encoding:

For some reason the SMS Messages do not arrive correctly in the Zimlets JSP. I can watch the correctly URL encoded message with LiveHttp Headers in FF or with wireshark. For some reason German and French Umlauts do not arrive in the JSP. Even when i try to log what the paramter like:

smsMsg = request.getParameter("msg");

zimletLog.debug("Param smsMsg: " + smsMsg);


Umlauts like öäü are just displayed as ???. Is there an issue with jetty?
3)Disabling of SMS Menu does not work

Seems like
enableContextMenuItem(this.PANEL_MENU,id,false);

in ZmZimletBase.js does nothing
4)Getting global properties in javascript for maxSMSLength

Was also unable to make
getConfigProperty(key);
working.
Any help is welcome!

I added zimlet zip file. config_template.xml should be commented enough to get it working.
Have fun, Christof.

ch_bnc_asterisk.zip



chlauber
Advanced member
Advanced member
Posts: 71
Joined: Fri Sep 12, 2014 11:41 pm

Asterisk PBX Integration Zimlet

Postby chlauber » Wed Oct 29, 2008 10:05 am

Needed to add -Dorg.mortbay.util.URI.charset=UTF-8 to var JAVA_OPTIONS in /opt/zimbra/etc/jettyrc



Seems that jetty uses other default URI encoding than UTF-8:

[QUOTE]Some drafts were prepared by various standards bodies suggesting that UTF-8 would become the standard encoding. Older versions of jetty (eg 4.0.x series) used UTF-8 as the default in anticipation of a standard being adopted. As a standard was not forthcoming, jetty-4.1.x reverted to a default encoding of ISO-8859-1.[/QUOTE]
See International Characters and Character Encodings - Jetty - Codehaus
Thus UTF-8 URI encoding seems default in AjxStringUtil.urlEncode(str) this would probably be a good idea to set this as default in Zimbra jetty?
chlauber
Advanced member
Advanced member
Posts: 71
Joined: Fri Sep 12, 2014 11:41 pm

Asterisk PBX Integration Zimlet

Postby chlauber » Mon Nov 03, 2008 7:19 am

Hi all
Have a new version of the ch_bnc_asterisk zimlet. Status of problems since first post:
1) Internationalization:

Still not working. Everything English
2) SMS encoding:

See last post. Adding -Dorg.mortbay.util.URI.charset=UTF-8 to JAVA_OPTIONS in /opt/zimbra/etc/jettyrc did the trick.
3)Disabling of SMS Menu does not work

Thus enableContextMenuItem(this.PANEL_MENU,id,false);

seems to have no implementation, menu cannot be disabled. If SMS sending disabled in zimlet config a message is sent that its administratively disabled when some tries to send a SMS.
4)Getting global properties in javascript for maxSMSLength

Works now. Zimlet Whitepaper is missleading. getConfigProperty('key') does not work. In other examples I found that getConfig('key') is used. And that one works.
Have fun!

ch_bnc_asterisk.zip

Horvath
Posts: 4
Joined: Fri Sep 12, 2014 11:52 pm

Asterisk PBX Integration Zimlet

Postby Horvath » Mon Nov 03, 2008 1:29 pm

I tryed to run this Zimlet by installing it in zimbra/zdesktop/jetty/webapps/service/zimlet/_dev in Zimbra Desktop 0.91 build 1344 on Mac OSX.
Menus work fine and I am able to configure my extension. When trying to dial however it shows the below message in the logs. Asterisk AMI never saw any connection attempt.
2008-11-03 14:08:31,154 ERROR [btpool0-32] [] log - Nested in org.apache.jasper.JasperException: PWC6033: Unable to compile class for JSP:

java.lang.NullPointerException

at org.apache.jasper.compiler.TagLibraryInfoImpl.(TagLibraryInfoImpl.java:234)

at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:482)

at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:562)

at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1626)

at org.apache.jasper.compiler.Parser.parse(Parser.java:165)

at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:223)

at org.apache.jasper.compiler.ParserController.parse(ParserController.java:124)

at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:184)

at org.apache.jasper.compiler.Compiler.compile(Compiler.java:398)

at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:592)

at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:344)

at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:477)

at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:371)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820)

at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)

at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093)

at com.zimbra.cs.zimlet.ZimletFilter.doFilter(ZimletFilter.java:202)

at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)

at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)

at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)

at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)

at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:716)

at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:406)

at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:211)

at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)

at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)

at org.mortbay.jetty.handler.RewriteHandler.handle(RewriteHandler.java:176)

at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)

at org.mortbay.jetty.Server.handle(Server.java:313)

at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:506)

at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:844)

at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:644)

at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)

at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:381)

at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:396)

at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:442)

2008-11-03 14:08:31,155 ERROR [btpool0-32] [] log - /service/zimlet/_dev/ch_bnc_asterisk/asterisk.jsp

java.lang.NullPointerException

at org.apache.jasper.compiler.TagLibraryInfoImpl.(TagLibraryInfoImpl.java:234)

at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:482)

at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:562)

at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1626)

at org.apache.jasper.compiler.Parser.parse(Parser.java:165)

at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:223)

at org.apache.jasper.compiler.ParserController.parse(ParserController.java:124)

at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:184)

at org.apache.jasper.compiler.Compiler.compile(Compiler.java:398)

at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:592)

at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:344)

at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:477)

at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:371)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820)

at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)

at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093)

at com.zimbra.cs.zimlet.ZimletFilter.doFilter(ZimletFilter.java:202)

at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)

at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)

at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)

at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)

at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:716)

at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:406)

at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:211)

at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)

at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)

at org.mortbay.jetty.handler.RewriteHandler.handle(RewriteHandler.java:176)

at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)

at org.mortbay.jetty.Server.handle(Server.java:313)

at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:506)

at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:844)

at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:644)

at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)

at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:381)

at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:396)

at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:442)

2008-11-03 14:08:45,305 ERROR [btpool0-32] [] log - Nested in org.apache.jasper.JasperException: PWC6033: Unable to compile class for JSP:

java.lang.NullPointerException

at org.apache.jasper.compiler.TagLibraryInfoImpl.(TagLibraryInfoImpl.java:234)

at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:482)

at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:562)

at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1626)

at org.apache.jasper.compiler.Parser.parse(Parser.java:165)

at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:223)

at org.apache.jasper.compiler.ParserController.parse(ParserController.java:124)

at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:184)

at org.apache.jasper.compiler.Compiler.compile(Compiler.java:398)

at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:592)

at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:344)

at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:477)

at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:371)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820)

at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)

at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093)

at com.zimbra.cs.zimlet.ZimletFilter.doFilter(ZimletFilter.java:202)

at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)

at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)

at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)

at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)

at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:716)

at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:406)

at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:211)

at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)

at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)

at org.mortbay.jetty.handler.RewriteHandler.handle(RewriteHandler.java:176)

at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)

at org.mortbay.jetty.Server.handle(Server.java:313)

at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:506)

at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:844)

at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:644)

at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)

at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:381)

at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:396)

at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:442)

2008-11-03 14:08:45,305 ERROR [btpool0-32] [] log - /service/zimlet/_dev/ch_bnc_asterisk/asterisk.jsp

java.lang.NullPointerException

at org.apache.jasper.compiler.TagLibraryInfoImpl.(TagLibraryInfoImpl.java:234)

at org.apache.jasper.compiler.Parser.parseTaglibDirective(Parser.java:482)

at org.apache.jasper.compiler.Parser.parseDirective(Parser.java:562)

at org.apache.jasper.compiler.Parser.parseElements(Parser.java:1626)

at org.apache.jasper.compiler.Parser.parse(Parser.java:165)

at org.apache.jasper.compiler.ParserController.doParse(ParserController.java:223)

at org.apache.jasper.compiler.ParserController.parse(ParserController.java:124)

at org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:184)

at org.apache.jasper.compiler.Compiler.compile(Compiler.java:398)

at org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:592)

at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:344)

at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:477)

at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:371)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820">HttpServlet.service(HttpServlet.java:820)

at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)

at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093)

at com.zimbra.cs.zimlet.ZimletFilter.doFilter(ZimletFilter.java:202)

at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)

at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)

at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)

at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)

at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:716)

at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:406)

at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:211)

at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)

at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)

at org.mortbay.jetty.handler.RewriteHandler.handle(RewriteHandler.java:176)

at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)

at org.mortbay.jetty.Server.handle(Server.java:313)

at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:506)

at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:844)

at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:644)

at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)

at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:381)

at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:396)

at org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:442)


I also tried to deploy the zimlet to my Zimbra Server (5.0.8_GA_2462.RHEL5_64.NETWORK) but the window that should display my configuration for extension won't open. I tried looking in the logs on the server but was unable to see any errors for the zimlet in mailbox.log perhaps I should be looking somewhere else for the error log. The documentation on the zimbra wiki is a bit sparse on how to debug zimlets. Any pointers on how to debug the zimlet on the server?
Thanks,

Horvath
chlauber
Advanced member
Advanced member
Posts: 71
Joined: Fri Sep 12, 2014 11:41 pm

Asterisk PBX Integration Zimlet

Postby chlauber » Mon Nov 03, 2008 2:43 pm

Sorry, it does not work with the Zimbra Desktop version. The zimlet has a JSP part and for some reason the Zimbra Destop does not include some JSP Tag Libraries that are needed in the zimlets JSP. Neither it has the tools to configure the zimlets config. So you need a full zimbra installation. It works with the Open Source Edition as well as with Network Edition.
Basically it's been installed like any other zimlet. See also adminstation guide chapter 13.1 .
CLI example for a Linux server:



1) copy ch_bnc_asterisk.zip to /opt/zimbra/zimlets


scp ch_bnc_asterisk.zip zimbra@zdev:zimlets/

2) Install as user "zimbra"

zmzimletctl install zimlets/ch_bnc_asterisk.zip

3) Get configuration template and edit configuration to your needs.

zmzimletctl getConfigTemplate zimlets/ch_bnc_asterisk.zip > /tmp/ch_bnc_asterisk_config.xml

vi /tmp/ch_bnc_asterisk_config.xml


4) Configure zimlet

zmzimletctl configure /tmp/ch_bnc_asterisk_config.xml


5) restart mailboxd

zmmailboxdctl restart


This is the only part that is not usual for installing a zimlet. This is because a zmzimletctl install does not load the needed jar file included in the zimlet.


Note: The dial-on click regexp is currently made for european style. So its expected that a phone number starts with 0 or +. So american style phone numbers like 1-1234-56789 are currently not catched. Try +1123456789 instead. If you are familiar with regexp you can change it in ch_bnc_asterisk.xml zimlet descriptor file.
chlauber
Advanced member
Advanced member
Posts: 71
Joined: Fri Sep 12, 2014 11:41 pm

Asterisk PBX Integration Zimlet

Postby chlauber » Tue Nov 04, 2008 8:27 am

Forget the previous posts about the solution. I was trapped by the LANG variable of the zimbra user. I was testing with a deploy script that does ssh -c "zmmailboxdctl restart" after installing the zimlet. So with this ssh command the LANG variable was set to en_US.UTF-8. But when logging on the zimbra server it was C. That caused a lot of confusion to me and lead me to a solution that was in fact none.

So the only simple solution is to change die LANG variable of the zimbra user to use UTF-8 encoding:

Change the LANG variable in /opt/zimbra/.bash_profile to en_US.UTF-8
chlauber
Advanced member
Advanced member
Posts: 71
Joined: Fri Sep 12, 2014 11:41 pm

Asterisk PBX Integration Zimlet

Postby chlauber » Tue Nov 04, 2008 9:21 am

For the client part it may help to just open the Firefox Error Console. (JavaScript errors)

If you want do debugging on the server part, you can see set the zimlet JSPs debug output when setting the log level for the zimelts to DEBUG.

Configure this the following way:

Add the following line to /opt/zimbra/conf/log4j.properties.in:



log4j.logger.zimbra.zimlet=DEBUG


After editing log4j.properties.in you need to restart mailboxd: zmmailboxdctl restart. Then watch logfile /opt/zimbra/log/mailbox.log.
The Zimbra server does some caching. So after installing a new Zimlet or new Version its a good idea to restart mailboxd and to do a logoff/login.
uxbod
Ambassador
Ambassador
Posts: 7811
Joined: Fri Sep 12, 2014 10:21 pm

Asterisk PBX Integration Zimlet

Postby uxbod » Tue Nov 04, 2008 9:23 am

This looks very exciting and kudos to you :) Will have a play at the weekend. Would be really nice to get more integration with Asterisk, so something like the ComCast SmartZone could be achieved.
Horvath
Posts: 4
Joined: Fri Sep 12, 2014 11:52 pm

Asterisk PBX Integration Zimlet

Postby Horvath » Tue Nov 04, 2008 12:36 pm

Thanks chlauber,
The only thing I missed was the zmmailboxdctl restart.
I am unable to test the SMS feature as I don't have any carriers that will terminate SMS but click-to-dial worked perfectly after I changed the regex to cover the North American dial plan.
Have you looked at com_zimbra_phone? I had to disable that zimlet in order to get this one working. It might be nice to add an additional menu like they have to add a contact. Their license may not be compatible with GPLv3 (haven't looked).









The only other thing I noticed was that the icon for Asterisk does not show in the listing of zimlets.
chlauber
Advanced member
Advanced member
Posts: 71
Joined: Fri Sep 12, 2014 11:41 pm

Asterisk PBX Integration Zimlet

Postby chlauber » Tue Nov 04, 2008 12:53 pm

Thanks for the feedback. NO i did not yet play with com_zimbra_phone. So i will check this.

I have a question because of the zimlets icon problem. Do you use ZCS 5.08? There was bug 30442 that caused other zimlets to invalidate the zimlets css. The quick fix is to remove the ';' at the end of css class ImgULogo in the local.css of com_zimbra_local zimlet.

Return to “Zimlets”

Who is online

Users browsing this forum: No registered users and 2 guests