DBConan Zeta

Right now I’m porting DBConan to C++, specifically using the QT framework (version 4.5.3). I’ve never programmed in C++ before, so the problem I’m posting here actually is an (embarrassing) basic problem in C++: it doesn’t compile :), with error message “file f_primaryKey has incomplete type”. The source code of the domain model is available here (yes, as a devout OO programmer I always start with the domain model) :D.

screen_dbconanzeta

For those who are experienced in C++, please help me identify what exactly is the problem. I did all I knew: I’ve forward-declared the class PrimaryKey (see the top of DomainModel.h). No luck.

UPDATE: Found why. Here is the fixed code (separate file, those interested -- including myself, for not getting into the same issue -- can compare it with the earlier version). In a few words, it's another wrinkle I just learned in C++: when you declare "PrimaryKey primaryKey;" as an instance variable of "Table", I guess the compiler will look for the empty-args constructor of PrimaryKey, somewhere in the code, before the declaration of class Table. Of course, in this case, the forward declaration of PrimaryKey doesn't help as it only declares the type, not the constructors. So, the solution: use pointer. So, instead of "PrimaryKey primaryKey;", try "PrimaryKey* p_primaryKey;". Another possible way out (I think): partial class..., but there's no such thing in C++ :). Keywords for google: +"field has incomplete type" C++

Hope that helps (I also googled using that phrase, but I didn't really find a direct / specific answer). I figured out what I explained above by doing some quick experiments.
Ok, why C++? Well, I’ve never programmed in C++, though I always wanted too. The original DBConan – the prototype – was writen in Python because I had to run it on a UNIX machine, on which I didn’t have permission to install Java…, python was my only choice. It turned out to be a good thing for me, I could appreciate python more.

Then, as I already stated in the presentation, this DBConan will have to have a GUI. For usability, analytic functions (which would be really difficult to use without GUI), eye-candies, etc. I decided not to use Java (swing) simply because… I’ve done Java for too many years. I need some change :). I’ve heard that QT is one of the better GUI framework out there, and it’s in C++. I read the book on programming QT (3 years ago), I liked it, and finally now I have a good excuse to use it :).

One of my first concerns was: memory management. As I wrote in my earlier post, in my understanding, in (standard) C++ we have to worry about who is responsible for deleting objects created (e.g.: the calling functions? or the one got passed in the object?). I know there’s auto_ptr in standard C++, but since I’m in QT why don’t we use what QT provides (and work well with the rest of QT framework). So I skipped auto_ptr entirely and go straight to QSharedData and QSharedDataPointer. In my case I decided to use QExplicitlySharedDataPointer, since I think it’s the model that resembles most closely the model in Java / C# that I’m familiar with.

Ok, I’m thinking here, guys, especially uni students: if you are interested in building something useful, using QT, for your thesis maybe, why not consider working with me on this?
Well, I found DBConan quite useful. In my previous project in Nextel Mexico, the vendor required us to include relevant snapshot of the database whenever we report an issue / finding. Initially I did it the “normal way” (during learning phase): I did the querying manually, hoping from one table to another, and stop when I think I’ve covered the required subset. I quickly realized it was a waste of my time, so I wrote DBConan that allowed me to “slurp” the data quickly. I think this can be used in other situations that involve working with large and complex database structure.

Please email me if you’re interested. Favor de escribirme si te interesa. Silahkan menyurati saya (email) jika anda tertarik. raka.angga@gmail.com. It has to be in QT 4.5.x.

My current flow of thinking (related to charging)

I'm digging old archives again, reviewing several charging scenarios I implemented in the rating & biling project in a mobile operator in Mexico throughout 2008-2009 (that uses a product named BSCS iX from LHS), trying to recall / rediscover the usage parameters that matter for telco operators (one of my current company's target market).

From there, try to understand why those parameters -- and relevant charging rules -- matter to them. That's the high-level objective.

Once we have a better / more solid idea about parameters & the charging rules, we can go backward, to identifying places in our application where we can / should tap those parameters from. The objective is to make the application "charging friendly". By that I mean, the design facilitates the need to provide the usage parameters asked by the charging system (supposedly owned by the telco operator).

After that, go forward again (to the middle). At that point we will have to verify if the data we have tapped from our application really is useful / usable. A test bed will be required. In this case, the test bed would a charging system, similar to the one(s) used by the telco operators. I will be looking into OpenRate soon.

Coming out of that we will have more confidence that we have more / sufficient knowledge to be able to deal with requests from the client (telco operator) for anything related to their charging requirements.

I'll post again once I have managed to try out OpenRate.

List of things I tend to forget how to do....

  • Configuring DNS + SRV records for SIP.
  • Using tcpdump (command line).
  • Using sox to convert wav to gsm.
I guess I have to put a quick note for oft-used commands somewhere..., here.

Right now I'm trying to get AG-Project's CDRTool working on a Debian. It works together with OpenSIPS. I will use it as a testbed for charging alternatives we're trying to come up with for our solution offering. We're heading toward Diameter-based solution (since Diameter is the thing recommended for IMS). However, we're still in search for an opensource / free diameter server component (specifically CDF), and we haven't found one. So, we'll use this CDRTool (together with OpenSIPS and it's Radius accounting module) as a temporary solution. Let's see if it works.

Now, first I need to get this OpenSIPs taking registration for a domain (e.g.: mytelco.net). For that I need to create SRV records, somewhere in the BIND configuration. Done that before, but already forgot how. Geez :). I hope this one would work: http://www.anders.com/cms/263 ... or this... http://sipx-wiki.calivia.com/index.php/DNS_Configuration

UPDATE: Ok, done. At least now my OpenSIPS handles registrations & requests for domain "mytelco.net". I put here screenshots and quick notes. They summarize a couple of things I learned from various resources on the web during the setup (useful for future reference).

(1) Get OpenSIPS installed. For basic usage (as simple forwarding proxy) it is pretty straightforward, just follow the instructions on this page: http://bit.ly/cgFNxy. I used version OpenSIPS 1.6.1 on Debian 5, by the way. Please note, there's a little error in that manual: the author mistyped the db password for user 'opensips'. The two GRANT lines at the end, they should've been like this:
GRANT ALL PRIVILEGES ON *.* TO opensips@localhost IDENTIFIED BY 'opensipsrw';
GRANT ALL PRIVILEGES ON *.* TO opensips@127.0.0.1 IDENTIFIED BY 'opensipsrw';
(2) Install BIND9: apt-get install bind9
(3) Configure BIND9: create zone files (forward and reverse), register them (in named.conf.local), reload bind (/etc/init.d/bind9 reload). See picture:



Right after that, modify resolv.conf (so that your Debian use the local DNS you just configured), and verify. See picture:



One obvious caveat here: if you use use dynamic IP (as in my case), you will have to repeat doing those steps (in the two pictures above) everytime you restart your machine (change the IP in the bind conf, and re-edit the resolv.conf).

Link to pages I read for configuring this thing:
(3) Modify OpenSIPS config files: (1) /usr/local/etc/opensips/opensipsctlrc, and (2) /usr/local/etc/opensips/opensips.cfg. In the first file, modify the value of the property named SIP_DOMAIN to mytelco.net. In the second file, add this line:
alias=mytelco.net
That's it, and finally start your OpenSIPS: /etc/init.d/opensips start

The modification for file #2, I learned it from http://advantia.ca/references/opensips-1.5/INSTALL . Prior to doing that, I always got error 483 (too many hops) when trying to register from my SIP phone. I guess putting that alias is a quick fix (hey it works!), I yet have to see the surprises though (hope there's none!).

Finally, here's the configuration on the client side (X-Lite 3.0 on MS-Windows):



Now, on to the ugli(er) part: getting CDRTool working. I did that once as well, partially, also, forgot how to do it.... I will post the result once I get it done. Documentation was really scarce and inaccurate :|.

Alright, no I'm going to create a copy of my Debian's virtual harddisk. Chau!
UPDATE: This is so dissapointing. I thought after a year the situation of OpenSIPS & CDRTool has improved. Nope. Install guide of CDRTool is still inaccurate. Furthermore, although the latest release of CDRTool seems to be built in 2010, the install manual is still linked to FreeRadius 1.1.3!!! The latest version of Freeradius we have in Debian repository is: 2.0.x. Worse, CDRTool install guide doesn't mention that fact (you'll notice it only if you open the readme of the patch it provides for freeradius).

Gee.... Ok, I think I should forget CDRTool. All I need from OpenSIPS is just the usage data, raw CDR as generated by the OpenSIPS (which I will feed in to a better, more professionally-documented rating engine). So, goodbye CDRTool, adios, chau chau. I really doubt the authors if the authors of CDRTool spent some efforts to make sure it's usable for ordinary people like me.

Right now I'm reading the manual for enabling radius accounting in OpenSIPS: http://www.opensips.org/Resources/DocsTutRadius ... Alas! found some typos (filename, section 3.2., they should have typed radiusclient.conf instead of radiusclient-ng.conf). Also, in that same section, I'm kind of stuck trying to figure out what line to put in /etc/freeradius/clients.conf. Why, oh, why can't they reach the level of Asterisk (I'm referring to availability of QUALITY manuals / references).

Cataroo Presentation – Part 2 – Test cases

Here it is, part 2 of the presentation about Cataroo. In this part I explain a couple of points related to defining test-cases for the sample application (callback). While I’m at it, I also touch a couple of relevant points about the design of the sample application. I believe, to excel, a Software Development Engineer in Test (SDET), just like his SDE counterpart, has to have a firm knowledge of software design. Without further ado, I hope you enjoy this part!

That stylistic figurine in the video-still is wayang (shadow puppet, a form of art spread throughout Asia. It flourishes especially in Java and Bali).

Just came to know a couple of days ago (from youtube) a very cool group based in the US that innovates on wayang, ShadowLight Productions. Thirty years perfecting the techniques, onward. That is dedication. I invite you to check out one of their works, Ambrosia of Immortality.

The short clips I used in my video are Punjabi songs I like a lot (for the beat & also for the dancing):

Ok, back to tech topic :), just realized that this small series of presentations about Cataroo is actually what I had in mind for segment 2 of my IMS video-series.

Sharing: SIP-based call-recording application

I found this when I was digging my old archives last weekend:
It was a quick slides I made to highlights the design of a (prototype of) call-recording application we implemented in late 2008. As you can see in the slides, this application facilitates both manual and automatic recording of calls made with contact-center agents.

The recording itself is achieved by dragging the contact-center agent and the customer into a dynamically-created conference room, and have a silent-participant in the room, taping the conversation.

It is a sub-optimal solution. A better one would be to use things like mediaproxy or rtpproxy (have the RTP streams in the call go through that proxy, and tap the packets right there). The reason we designed it that way -- using conference -- is because they wanted to make use of the media server (with support for conferencing) that they have bought.

The source code is opened now; should serve as an additional resource for you who just started SIP-application development. I don't have time at this moment to write a how-to deploy and run it, less the detail of the design & code.

I invite you to do it. If you'd like to take that invitation, please write me an email at raka.angga@gmail.com or you can simply drop a comment here. Your help on this will be greatly appreciated, and it would really help fellow engineers out there.