Gone for a while…

gone from blogging, but not from working ūüėČ

I’ll, eventually, explain these projects with more detail, but for now, I will just enumerate them so people can have a clue of what I’ve been working on:

1. cnxcc: this is a credit control module for Kamailio which deals with customers credit information to monitor the calls and hang them up if necessary.

2. cnxcc-db-sync: a php script to query the previous module (via xmlrpc) in order to feed a database with information coming directly from the module’s internal memory, really fresh and real time information.

3. cnxcc-web: a web based management interface for cnxcc.

4. webrtc + websockets: I’ve been reading a lot about this subject. I’ve even bought a book ūüėÄ

Dinstar SMS API client

I just committed the project that uses libdwgsms to send/receive text messages through Dinstar’s branded gateways.

The code goes as simple as follows, and you can check it from my github account:

Contact Form gone

I¬†accidentally¬†discovered that the emails coming from the contact form were marked as spam. For some reason, Google thinks that emails coming from the IP hosting this blog are spam so I’ll temporarily disable the contact page until I figure out what happened.

I don’t know how many mails were lost since I published this blog but at least one was saved thanks to an accidental click on the spam link of my gmail account.

If you sent me a contact request using that form and you did not receive any answer, I’m sorry but nothing arrived to my inbox :(, I always reply to people’s queries.

Status update

At work, I was assigned to the job of building a Kamailio module to maintain track of in-progress calls and to hang them up when the credit was exhausted or just reject them when no credit is available.

This task is taking me more than I thought and its complexity is getting even bigger which directly impacts in my regularity here. I enqueued most of my off-work projects and my time here lowered significantly.

The good news is that I becoming really fluent with Kamailio core programming and this is somehow good because I’m staying in the path of VoIP which will take me to become the expert that I want to be someday.

I hope to be back soon.

PJSIP and Huawei modems to build opensource gateway

I am amazed with the power of pjsip¬†for building low footprint apps in really short periods of time. Although it is not easy to do it, there are a bunch of ready-to-use examples to try out which makes relatively easy to have working user-agents fast. My last personal project was the answering machine¬†and now I’m wanting to¬†expand¬†the idea in something more useful and to turn the project into an opensource GSM gateway independent to any SIP server or B2BUA like Asterisk.

I already started studying the docs and I have to say that pjsip is really powerful and has nothing to envy to other SIP related projects like SIP-ROUTER even if they target different kind of users.

My goal in summary goes as follows:

  1. Write a SIP user agent using PJSIP.
  2. Write a gateway for translating SIP to AT commands, and backwards.
  3. Write a media subsystem to make interaction between the modem and PJMEDIA.
  4. Release the code to the community.

It’s an ambitious project but the willingness is present and time could be the only inconvenient since my blog and personal projects are completely¬†maintained¬†outside office hours. I talked about this to my boss who is very open and gave me his support so hopefully I’ll be showing some advances here soon enough.

OpenSIPS course

I’m attending to a development course (via gotowebinar) for OpenSIPS¬†SIP router for which I had a lot of expectations that, so far, are all fulfilled. The course is held by Bogdan Iancu and¬†Vlad Paiu, two great professionals with a lot of background in the field and whom I consider to be an example of success in opensource VOIP technology.

I have a little of experience building modules for the old OpenSER project and this particular experience is putting me in the front seat for asking question and absorbing knowledge. I’ve been reading about this for some time and my primary objective is to become and expert on these technologies and to be able to contribute to the community like these two great professionals are doing it right now.

 

Generador de letras de reggaetón

Disclaimer: this is completely unrelated to computer science or VOIP :D.

Este post es mi respuesta a @mharcos y @markosbenitez quienes me desafiaron a hacer un programa que genere letras de reggaetón a partir de unas instrucciones (abajo) posteadas en facebook.

Con un script hecho en PHP fui capaz de generar letras como esta:

Gata yo quiero azotarte fuerte hasta manhana
Chica yo quiero cogerte lento hasta manhana
Chica vamos a castigarte duro hasta manhana
Perra vamos a cogerte fuerte hasta que salga el sol

[CORO]
azotarte azotarte azotarte, toda la noche, suave … x3

Perra vamos a castigarte duro todo el dia
Perra yo voy a castigarte duro hasta manhana
Gata vamos a cogerte suave todo el dia
Chica yo quiero encenderte rapido hasta el amanecer

[CORO]
azotarte azotarte azotarte, toda la noche, lento … x3

Perra yo quiero darte suave hasta manhana
Mami yo vengo a azotarte lento hasta que salga el sol
Chica yo voy a encenderte suave hasta el amanecer
Chica vamos a castigarte lento hasta el amanecer

[CORO]
darte darte darte, hasta que salga el sol, suave … x3

Con éste enlace podés generar más letras aleatorias. Con cada recarga se genera una nueva.

Para los entendidos del tema, ac√° les dejo el script.

[php]

define(‘RENGLONES_POR_ESTROFA’, 4);
define(‘MAXIMO_ESTROFAS’, 3);
define(‘NL_MARKER’, “n”);

$bloque_1 = array(‘Mami’, ‘Gata’, ‘Perra’, ‘Zorra’, ‘Chica’);
$bloque_2 = array(‘yo quiero’, ‘vamos a’, ‘yo voy a’, ‘yo quiero’, ‘yo vengo a’);
$bloque_3 = array(‘castigarte’, ‘cogerte’, ‘encenderte’, ‘darte’, ‘azotarte’);
$bloque_4 = array(‘duro’, ‘rapido’, ‘lento’, ‘suave’, ‘fuerte’);

$bloque_5 = array(‘hasta que salga el sol’,
‘toda la noche’,
‘hasta el amanecer’,
‘hasta manhana’,
‘todo el dia’);

$bloque_6 = array(‘sin miedo’,
‘sin anestesia’,
‘en el piso’,
‘contra la pared’,
‘sin compromiso’);

function GenerarLetra()
{
$estrofa = array();
$letra = array();

for ($i = 0; $i < MAXIMO_ESTROFAS; $i++)
{
$estrofa = array();

for ($j = 0; $j < RENGLONES_POR_ESTROFA; $j++)
array_push($estrofa, GenerarRenglon());

array_push($letra, implode(NL_MARKER, $estrofa).NL_MARKER);
array_push($letra, “[CORO]”);
array_push($letra, GenerarCoro().” … x3″.NL_MARKER);
}

print implode(NL_MARKER, $letra);
}

print GenerarLetra().”n”;

function GenerarRenglon()
{
global $bloque_1, $bloque_2, $bloque_3, $bloque_4, $bloque_5, $bloque_6;

return “{$bloque_1[rand() % count($bloque_1)]} “.
“{$bloque_2[rand() % count($bloque_2)]} “.
“{$bloque_3[rand() % count($bloque_3)]} “.
“{$bloque_4[rand() % count($bloque_4)]} “.
“{$bloque_5[rand() % count($bloque_5)]}”;
}

function GenerarCoro()
{
global $bloque_3, $bloque_4, $bloque_5;

$verbo = $bloque_3[rand() % count($bloque_3)];

return “$verbo $verbo $verbo, {$bloque_5[rand() % count($bloque_5)]}, {$bloque_4[rand() % count($bloque_4)]}”;

}

 

[/php]

Espero les sirva de algo xD

Huawei modem as an answering machine

Here is a summary of my effort trying to make chan_dongle to work:

… I couldn’t …

and I don’t even tried, I’d rather prefer to write my own channel, but why? When three semi-functional projects with the same device and the same technology fails in completing their objectives, there must be something wrong with the approach probably because doing it as an Asterisk channel adds unnecessary complexity.

The project

I spent 2 days reading docs about AT and after I gained some expertise I tested them using minicom with an E177 modem. Everything worked as it should except for the audio.

Consider this scenario.

1. modem connected to USB port.
2. minicom opening data port (/dev/ttyUSB0 in most cases).
3. an external phone for making calls.

Now the test was as follows:

1. I called to the modem using the external phone.
2. I answered the call from minicom.
3. I started reading the audio port (/dev/ttyUSB1).
4. I hung up the call.

The signaling was fine, the call handling was fine but no audio was received from /dev/ttyUSB1. I wasted precious time looking for an answer because I was asking the wrong question, I even recurred to stackoverflow.com but without luck.

I explored chan_dongle‘s source tree expecting to find some missing initialization sequence but it’s really complicated to follow the code execution path on a heavily multi-threaded application like Asterisk so I decided to use strace to attach it to Asterisk’s PID and sniff for write syscalls to get a clue of what the channel was doing.¬†My guess certainly worked: I missed the AT^DDSETEX=<diag-port> after the call is connected so I repeated the test including this command right after the call was answered and suddenly an audio stream was flowing through the port.

[bash]

strace -f asterisk 2>&1 | grep write | grep AT
[pid 14715] write(17, “ATr”, 3 <unfinished …>
[pid 14715] write(17, “ATZr”, 4) = 4
[pid 14715] write(17, “ATE0r”, 5) = 5
[pid 14715] write(17, “AT+CGMIr”, 8) = 8
[pid 14715] write(17, “AT+CGMMr”, 8) = 8
[pid 14715] write(17, “AT+CGMRr”, 8) = 8
[pid 14715] write(17, “AT+CMEE=0r”, 10) = 10
[pid 14715] write(17, “AT+CGSNr”, 8) = 8
[pid 14715] write(17, “AT+CIMIr”, 8) = 8
[pid 14715] write(17, “AT+CPIN?r”, 9) = 9
[pid 14715] write(17, “AT+COPS=0,0r”, 12) = 12
[pid 14715] write(17, “AT+CREG=2r”, 10 <unfinished …>
[pid 14715] write(17, “AT+CREG?r”, 9) = 9
[pid 14715] write(17, “AT+CNUMr”, 8) = 8
[pid 14715] write(17, “AT^CVOICE?r”, 11) = 11
[pid 14715] write(17, “AT+CSCA?r”, 9) = 9
[pid 14715] write(17, “AT+CSSN=1,1r”, 12) = 12
[pid 14715] write(17, “AT+CMGF=0r”, 10) = 10
[pid 14715] write(17, “AT+CSCS=”UCS2″r”, 15) = 15

[/bash]

Answering machine

I decided to write a program to try out what I learned these days and this project came to my mind. It might not be the best execution of an idea but hopefully will help me to master the techniques required to make and receive phone calls using Huawei modems in a minimalist scenario where debugging is not a reason to shoot yourself in the face.

The program connects to the modem and waits for an incoming call which when received, is picked up and a prerecorded sound file is played to the caller. It’s a pretty straightforward idea and involves 80% of what is necessary to implement an Asterisk channel that does the same in another context.

[bash]$ /answering_machine /dev/ttyUSB0 /dev/ttyUSB1 /home/carlos/rec.raw [/bash]

– The 1st parameter is the data port.
– The 2nd paramater is the audio port.
– The 3th paramater is an arbitrary signed 16bit PCM 8000 Hz file.

Having supplied those arguments, the program picks up any incoming call and plays the file pointed by the third parameter.

You can find the code here and for now, to compile it you have to import it as an Eclipse project because the Makefile is missing (for now).

Dinstar DWG2000 SMS API stable release

I’ve finished the first stable release of the DWG2000 messaging API. I tested it dozens of times and appears stable after 24 hours of constant running. I’m aware of the memory leaks but I’ll fix this issue as soon as I can.

The code is pretty straightforward and self explanatory. By now this is just for personal use but if any of you are working with the same family of products, I can definitely help you. It is not ready for production, but it works.

[c]
/*
* main.c
*
* Created on: Mar 28, 2012
* Author: caruizdiaz
*/

#include “util.h”
#include “dwg/dwg.h”
#include “networking/ip_socket.h”

void new_sms_handler(dwg_sms_received_t *sms)
{
LOG(L_DEBUG, “new sms from %s. Len: %d, Text: %sn”, sms->number, sms->message.len, sms->message.s);
}

void status_handler(dwg_ports_status_t *status)
{
int index = 0;

LOG(L_DEBUG, “tNumber of ports: %dn”, status->size);

for (index = 0; index < status->size; index++)
{
LOG(L_DEBUG, “tPort%d: %dn”, index, status->status_array[index].status);
}
}

void msg_response_handler(dwg_sms_response_t *response)
{
LOG(L_DEBUG, “tResponse from %sn”, response->number);
}

int main(int argc, char** argv)
{

dwg_message_callback_t callbacks = {
.status_callback = status_handler,
.msg_response_callback = msg_response_handler,
.msg_sms_recv_callback = new_sms_handler
};

dwg_start_server(7008, &callbacks);

str_t des = { “0981146623”, 10 };
str_t msg = { “hola”, 4 };

for(;;)
{
getchar();
dwg_send_sms(&des, &msg);
}

}
[/c]