Wednesday, December 30, 2015

Fiat Panda windscreen wiper timer

My Panda, after almost 16 years of service, begins to show its years.
This time, the front  wiper does not work properly.
You may read almost evreywhere, Google is your friend....
About this matter, it seems nobody ever went deeper, and to my issue, which seems to be quite widespread, Google wouldn't helped that much; the only answer I found by it is "change the motor and its controlling circuit". This solution can be quite expansive, looking around for prices,  it seems you can not find it for less than 100€.
On the other hand, looking at the controlling circuit, it does not seem to be very complicated, so I decided to use some time to resolve my issue, and therefore save 100€.



As from the image I included in this post, circuit itself is not too complicated.
I also made some schemas to help myself in understanding its behaviour.

The switch appearing in the bottom of the schema, is embedded in the gear inside the transmission of the motor. Its rotation make the controller understand about the wiper position. It is a plastic gear with the core made of conductor material. It appears as follow:
Where the RED part is the metallic core, and the black lines is where contact from the control circuit goes.

Well, I guess this is the time where I tell you which is my problem, after all.
Problem is as follow:  the "SLOW" speed of the wipers does not work, and when it is set to the "FAST" speed, if you turn off the wiper it stops where it is, without return to its home postion.
After several hours of analysis, I found where the problem lies.
It is due to the oxidation of the normally open contact of the relay.





This way I saved myself more than 100€ for the spare part, I hope anyone else could found my info useful and save his money.

Friday, December 11, 2015

Block aggressive advertising calls

In my country, but I bet anywhere else do the same, the telephone calls for proposing new products are constantly increasing, these annoying calls, sometimes malicious, aren't always welcome.

My country has adopted a kind of institutional way to handle this phenomena, it is called  "registro pubblico delle opposizioni", using this, any citizen may publish his telephone number, merely this action should him guarantee he would never ever receive again any advertisement call.

Unfortunately, reality can't be more distant from what really is going to happen.

Telephone spammers do not use to follow rules, and the weak statement "this user does not want to be called for commercial purposes "  is not enough to prevent they to call you. 

If you do not want to be called, you have to find yourself a way to do that.
In other words, you have to find a way to recognize them as spammer, and forward them, for example, to an announce stating you do not want to be called.

As an Asterisk user I have a framework at my disposal, which potentially lets me route calls using any sort of policy; but the main issue is how to identify a spammer?

Internet community, seems to have faced this problem and has built a kind of database in which people complaints about telephone numbers.

It exists, for example, a service called TELLOWS on which anyone can leave a comment on a source telephone number.

So why don't use those information to identify spammers and avoid unwanted telephone calls?

My proposal is integrate the service provided by TELLOWS in the Asterisk dialplan.

Here an example of my thougths.

in the Asterisk dialplan
exten =>  incoming,       1,              Noop(Incoming call is just arrived)
exten =>  incoming,       n,              Set(tellowsc=${SHELL(tellows_c.sh ${CALLERID(num)})})
exten =>  incoming,       n,              GotoIf($[${tellowsc}>1]?reject)
exten =>  incoming,       n,              Dial(${destination},30,${FLAGS})
exten =>  incoming,       n,              HangUP()
exten =>  incoming,       n(reject),      Answer()
exten =>  incoming,       n,              Wait(2)
exten =>  incoming,       n,              Set(CDR(userfield)=RejectedByPolicy)
exten =>  incoming,       n,              Playback(spam)
exten =>  incoming,       n,              HangUP()
the bash script for the italian version of TELLOWS
#!/bin/sh
score=$(wget -O - -q "http://www.tellows.it/num/$1" | grep "/images/score/score[0-9].png" | grep scoreimage | sed -r 's/.*score([0-9])\.png.*/\1/');
comments=$(wget -O - -q "http://www.tellows.it/num/$1" | grep "itemprop" | grep "Numero di commenti:"| sed -r 's/.*>([0-9]+)<.*/\1/');
echo -n "$comments";
I used, to reject calls, the number of comments the number has, but there's also a kind of number score, you can use to take your decision




Thursday, October 22, 2015

JabberSend crashes your system if it has no connection with the XMPP server.

JabberSend is quite a useful function.
It lets you send xmpp instant messages, and it can be used for various things such as alert you when a call hits your voice mail or also that someone is calling you.

Here an example dial plan.
[outside_line]
exten =>  s, 1,  Noop(Incoming call is just arrived)
exten =>  s, n,  JabberSend(XMPP_Account,Jid@domain,Incoming call from "${CALLERID(num)}")
exten =>  s, n,  Dial(${GLOBAL(incoming_call_group)},30,${FLAGS_incoming})
exten =>  s, n,  JabberSend(XMPP_Account,Jid@domain,${CALLERID(num)} is leaving VM message)
exten =>  s, n,  VoiceMail(${GLOBAL(incoming_voicemail)}@asterisk)
exten =>  s, n,  Hangup()


Nice feature, but it comes with a big problem: if for any reason the XMPP connection is down, JabberSend crashes your Asterisk system.
This kind of behaviour is obviously not admittable in any kind of production environment.

You can however use it in a production environment making a slight modification to the code source code of res_xmpp.c

In the Asterisk version I'm using, the 11.6, modifying the function xmpp_client_send_message as follow, the result is:
if JabberSend is invoked and there's no connection to the xmpp server it logs a warning message instead of crashing the system.

here the code, the red indicates where I modified the original code:
static int xmpp_client_send_message(struct ast_xmpp_client *client, int group, const char *nick, const char *address, const char *message)
{
        RAII_VAR(struct xmpp_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
        RAII_VAR(struct ast_xmpp_client_config *, clientcfg, NULL, ao2_cleanup);
        int res = 0;
        char from[XMPP_MAX_JIDLEN];
        iks *message_packet;

        if (!cfg || !cfg->clients || !(clientcfg = xmpp_config_find(cfg->clients, client->name)) ||
            !(message_packet = iks_make_msg(group ? IKS_TYPE_GROUPCHAT : IKS_TYPE_CHAT, address, message))) {
                return -1;
        }

        if (!ast_strlen_zero(nick) && ast_test_flag(&clientcfg->flags, XMPP_COMPONENT)) {
                snprintf(from, sizeof(from), "%s@%s/%s", nick, client->jid->full, nick);
        } else {
                snprintf(from, sizeof(from), "%s", client->jid->full);
        }

        iks_insert_attrib(message_packet, "from", from);

        //begin//
        if (client->state == XMPP_STATE_CONNECTED) {
                                                    res = ast_xmpp_client_send(client, message_packet);
                                                   }
                                              else {
                                                    res = -1;
                                                    ast_log(LOG_WARNING, "XMPP: Not connected, unable to send messages to %s\n", client->name);
                                                   }
        //end//


        iks_delete(message_packet);

        return res;
}
I hope this can help.

Sunday, May 24, 2015

Access your PBX using voice channels

As VoIP PBX administrators we often have to deal with not so cooperative network administrators.
The IP PBXs depend from the underlying network infrastructure, as for their normal behaviour, as for their access remotely and not rarely happen to have to deal with very restrictive network policies.
I found frustrating the fact that network administrators implement their network policy, without any consult, ending at last denying any remote access to the infrastructure but their owns.
In such situations, change an extension name, say 400, becomes a time consuming task and you have to move to the client location and do it on site or in the best case scenario, you might have to ask to the client to use one of the PC equipped with some software such as Teamviewer.
If you ever had this kind of experiences, you know what I mean.

In this article I want to propose you, not the SOLUTION, but something you may use to mitigate the situation; requiring no extra hardware, nor human help.

Do you remember the old days when you had to use the analog modems to connect to the Internet?
Since at the time there were no digital lines or at least no cheap digital lines, the only solution were use modems.
Well, the solution I want to propose is indeed use voice lines, VoIP or not, in a similar way you used to do in such old days.
Before I show you my implementation, if you do not know already, let me introduce some piece of software I'll use to implement it.
  1. Linux Ham Radio AX25 software suite
  2. Alsa loopback device
  3. Asterisk Alsa channel
The very first question that might be asked is: Why use amateur radio software?
Well, reasons can be many. The most obvious is that this software is already there, it is quite old and tested. But if you need another, I can add that old modems produce a carrier that have to be kept for a connection long time, using a VoIP packet connection you may have latency problem, the same you have when FAXes do not work. Amateur Radio packet protocols produce a carrier only during the effective data transmission, therefore they are less prone to have latency issues.

The final idea should look such as the following images:


This solution won't let you connect your Asterisk server at the highest speed, with this method the best you can do is 38400bps, but at least you can remotely manage your installation without beg anyone's help for a remote access!

The implementation

The Amateur Radio AX.25

Make sure you have the hamradio kernel modules installed, you may check the presence of mkiss.ko in the /lib/modules/ directory to have an hint they're really there.

A note for RedHat derived distributions, this is true at least for RedHat Enterprise Linux 5, 6, correspondingly CentOS versions and possibly other distributions. Those distributions do not have hamradio kernel modules built, therefore you have to build your own.
The best I can suggest to the happy RedHat users is to download the kernel source using the yum utility, and then integrate all missing pieces (hamradio kernel modules) with the ones moved from the correspondent kernel sources taken from www.kernel.org. (here a guide to build kernel module on CentOS systems after you made the transplant)

Once you're sure kernel is ok, you may begin consider the user space utilities you need for this task.
My suggestion is build them your own from the sources.
Anyway you decide to do, make sure you have the followings packages:
  • ax25-apps
  • ax25-tools
  • libax25
  • soundmodem
The AX25 protocol stack is not so difficult to configure, in fact I had the only need to add only a row to the axports file in the /etc/ax25 directory. The axports defines the port names, their associated mappings.
Here an example:
sm0     HQH1            4800    255     2       Test connection
The fields in this file represent in order:
  • The name of the new interface you'll use to send packets through the voice link
  • The Callsign you'll use "on the air". This is the L2 address used by the ax25 protocol. In the real amateur radio field this is assigned by some authorities, but in our case anything would be fine.
  • The speed of communication between TNC and computer, in other words the speed of the communication between the kernel and the soundmodem, which is a software implementation of the TNC.
  • The MTU for this ax25 connection.
  • The ax25 window parameter.  It might be considered like 'maxframe'.
  • The description.
The next step is configure the soundmodem software, which is the actual modulator demodulator for the voice signal.
An example of its configuration is the following:
<?xml version="1.0"?>
<modem>
<configuration name="AX25">
<chaccess txdelay="150" slottime="100" ppersist="40" fulldup="1" txtail="100"/>
<audio type="alsa" device="plughw:Loopback,0,0" halfdup="0" capturechannelmode="Mono"/>
<ptt file="none" hamlib_model="" hamlib_params="" gpio="0"/>
<channel name="sm0">
<mod mode="fsk" bps="4800" f0="1200" f1="2200" diffenc="1" inlv="8" fec="1" tunelen="32" synclen="32" filter="df9ic/g3ruh"/>
<demod mode="fsk" bps="4800" f0="1200" f1="2200" diffdec="1" inlv="8" fec="3" mintune="16" minsync="16" filter="df9ic/g3ruh"/>

<pkt mode="MKISS" ifname="sm0" hwaddr="HQH1" ip="23.0.0.1" netmask="255.255.255.0" broadcast="23.0.0.255"
file="/dev/soundmodem0" unlink="1"/>
</channel>
</configuration>
</modem>

This is proved working, but it is also slow, 4800 bps! If your voice path is clear, there space to get faster.
I divided the configuration in coloured sections:
  • orange: This section specifies the media access. I used some default settings, but consider the media we're trying to use is far much different from the one intended for this use. Our media is full duplex; and we do not really need to respect time constraints like time slots nor tx delays.
  • magenta: This section specifies the actual alsa hardware we're are going to use. I plan to explain in more details in the next section "Alsa loopback device" but let's say that in this section we should specify an alsa aloop device channel preceded by the suffix "plug" which is need for resampling issues.
  • yellow: This section specifies the channel settings and the binding with the actual Linux interface, in this case sm0.
  • green: This sections specify the modulation and demodulation method, the throughput and frequencies involved. Feel yourself free to try various combinations to find the best in your situation.
  • cyan: This section specifies the packet mode setting parameters. In this section you assign the layer 2 and layer 3 address for your connection.

Alsa loopback device aloop

The only reason this piece of software is there, is because we want to interface Asterisk with the soundmodem device. They both use an alsa device as input/output therefore the alsa loopback device is the natural way to interface them. The aloop is present in every Linux distribution I know, so it shouldn't be difficult to find one ready to be used.
In most situation the only need is to load the aloop module into the kernel.
modprobe snd-aloop
This should result in 8 new channels ready to be used
 card 2: Loopback [Loopback], device 0: Loopback PCM [Loopback PCM]
  Subdevices: 8/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
  Subdevice #7: subdevice #7
card 2: Loopback [Loopback], device 1: Loopback PCM [Loopback PCM]
  Subdevices: 7/8
  Subdevice #0: subdevice #0
  Subdevice #1: subdevice #1
  Subdevice #2: subdevice #2
  Subdevice #3: subdevice #3
  Subdevice #4: subdevice #4
  Subdevice #5: subdevice #5
  Subdevice #6: subdevice #6
  Subdevice #7: subdevice #7
we need just one of those channels, so you may tweak the module loading with options specifying in the modprobe.conf, or whatever your distribution has to specify kernel modules parameters.

Asterisk

The Asterisk part of the configuration makes use the uncommon chan_alsa.
The Asterisk Alsa channel driver has been originally developed to let use the server console be used as endpoint in the telephony system. Chan_alsa as its name suggest uses an alsa capable devices to direct the voice stream.
The only thing we need to tweak in the alsa.conf original configuration is the alsa device to be used, the aloop device.
[general]
autoanswer=yes
context=local
extension=s
input_device=plughw:Loopback,1,0
output_device=plughw:Loopback,1,0

At this point, directing a call to this end point we created a leg of the tunnel.
Eg. in extensions.conf
exten => 929,           1,              Dial(Console/snd/controlC0,30)

Note:
In actual tests of the tunnel, in spite ax25 is seen as a kind of ethernet, and implements an arp style level 2 address resolution, I had to set it manually.
If it happen you have the same issue, the arp syntax for ax25 bindings is:
arp -H ax25 -s 23.0.0.1 HQH1





Monday, February 16, 2015

Google Talk ends its services, now what?

Due to the decision Google made to turn off its xmpp service talk, I've been forced to migrate another xmpp service.
I thought it would be an easy task, just put new data into xmpp.conf and it's done. But it didn't go that way.
As soon as I run the new configuration, I got:

<--- XMPP sent to 'tigase.im' --->
<?xml version='1.0'?><stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='jabber:client' to='tigase.im' version='1.0'>
<------------->

<--- XMPP received from 'tigase.im' --->
<?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' from='tigase.im' id='6be9205d-5793-4ae6-84e0-afd0983ed490' version='1.0' xml:lang='en'>
<------------->

<--- XMPP sent to 'tigase.im' --->
<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>
<------------->

<--- XMPP received from 'tigase.im' --->
<stream:features><sm xmlns="urn:xmpp:sm:3"/><register xmlns="http://jabber.org/features/iq-register"/><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/><ver xmlns="urn:xmpp:features:rosterver"/><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"><required/></starttls><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression></stream:features>
<------------->

<--- XMPP received from 'tigase.im' --->
<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
<------------->
[Feb 16 19:20:56] ERROR[20733]: res_xmpp.c:2558 xmpp_client_requested_tls: TLS connection for client 'tigase.im' cannot be established. OpenSSL initialization failed.
[Feb 16 19:20:56] WARNING[20733]: res_xmpp.c:3571 xmpp_client_receive: Parsing failure: Hook returned an error.
[Feb 16 19:20:56] WARNING[20733]: res_xmpp.c:3635 xmpp_client_thread: JABBER: socket read error

What the hell was there?
I reviewed all the res_xmpp parameters, but at last I had to accept to the fact it doesn't work.
A xmpp provider related issue?
Might be, but changing to another xmpp service didn't help, and connection kept fail.

Debug log states it is a TLS connection related problem...
I started my investigation on iksemel, the xmpp parser library.
It has its own tls mechanism based on gnutls, which is independent with the one implemented in res_xmpp, but at that time I didn't know yet.

There is a tool in the "tool" directory of the iksemel library which performs a simple xmpp connection.
It is the iksroster.
Using that to test the xmpp connection I got a TSL connection error.

Looking at the code, the I found in the src/stream.c file that function handshake performs the negotiation for the TLS connection:

static int handshake (struct stream_data *data)
{
        const int protocol_priority[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
        const int kx_priority[] = { GNUTLS_KX_RSA, 0 };
        const int cipher_priority[] = { GNUTLS_CIPHER_3DES_CBC, GNUTLS_CIPHER_ARCFOUR, 0};
        const int comp_priority[] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 };
        const int mac_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 };
        int ret;

        if (gnutls_global_init () != 0) return IKS_NOMEM;              
        if (gnutls_certificate_allocate_credentials (&data->cred) < 0) return IKS_NOMEM;       
        if (gnutls_init (&data->sess, GNUTLS_CLIENT) != 0) {
                                                            gnutls_certificate_free_credentials (data->cred);
                                                            return IKS_NOMEM;
                                                           }
        gnutls_protocol_set_priority (data->sess, protocol_priority);
        gnutls_cipher_set_priority(data->sess, cipher_priority);
        gnutls_compression_set_priority(data->sess, comp_priority);
        gnutls_kx_set_priority(data->sess, kx_priority);
        gnutls_mac_set_priority(data->sess, mac_priority);
        gnutls_credentials_set (data->sess, GNUTLS_CRD_CERTIFICATE, data->cred);

        gnutls_transport_set_push_function (data->sess, (gnutls_push_func) tls_push);
        gnutls_transport_set_pull_function (data->sess, (gnutls_pull_func) tls_pull);
        gnutls_transport_set_ptr (data->sess, data->prs);

        ret = gnutls_handshake (data->sess);
        if (ret != 0) {
                       gnutls_deinit (data->sess);
                       gnutls_certificate_free_credentials (data->cred);
                       return IKS_NET_TLSFAIL;
                      }
        data->flags &= (~SF_TRY_SECURE);
        data->flags |= SF_SECURE;
        iks_send_header (data->prs, data->server);
        return IKS_OK;
}

The code shows the function is using a deprecated chiper, it could be the reason why TLS connection fails.
A test that worth to try is add another more recent cipher.
const int cipher_priority[] = { GNUTLS_CIPHER_AES_256_CBC,GNUTLS_CIPHER_AES_128_CBC,GNUTLS_CIPHER_3DES_CBC, GNUTLS_CIPHER_ARCFOUR, 0};
Indeed The new version made the trick, and that time on, iksroster successfully connected to the server.
In the asterisk console however, no change.
Looking with attention to the res_xmpp.c code, I finally got the problem: asterisk does its own TLS connection using OpenSSL, and it is bound to use SSLv3.
You can be more lucky than me, but it seems not many xmpp servers are using SSLv3!
You can test yourself  you xmpp provider using the tools provided by https://xmpp.net/, in my case, tigase.im used TLSv1.2.
The only way I found to make my connection work has been patch my res_xmpp.c to use TLSv1.1

static int xmpp_client_requested_tls(struct ast_xmpp_client *client, struct ast_xmpp_client_config *cfg, int type, iks *node)
{
#ifdef HAVE_OPENSSL
        int sock;
#endif
        int dbg_info=0;

        if (!strcmp(iks_name(node), "success")) {
                /* TLS is up and working, we can move on to authenticating now */
                xmpp_client_change_state(client, XMPP_STATE_AUTHENTICATE);
                return 0;
        } else if (!strcmp(iks_name(node), "failure")) {
                /* TLS negotiation was a failure, close it on down! */
                return -1;
        } else if (strcmp(iks_name(node), "proceed")) {
                /* Ignore any other responses */
                return 0;
        }

#ifndef HAVE_OPENSSL
        ast_log(LOG_ERROR, "Somehow we managed to try to start TLS negotiation on client '%s' without OpenSSL support, disconnectin$
        return -1;
#else
//        client->ssl_method = SSLv3_method();  //this was the original
        client->ssl_method = TLSv1_1_method();
        if (!(client->ssl_context = SSL_CTX_new((SSL_METHOD *) client->ssl_method))) {
                dbg_info=1;
                goto failure;
        }

        if (!(client->ssl_session = SSL_new(client->ssl_context))) {
                dbg_info=2;
                goto failure;
        }

        sock = iks_fd(client->parser);
        if (!SSL_set_fd(client->ssl_session, sock)) {
                dbg_info=3;
                goto failure;
        }

        if (!SSL_connect(client->ssl_session)) {
                dbg_info=4;
                goto failure;
        }

Now my connection works.

I hope you find this useful.