yeah, tudo assíncrono!

Ultimamente tem sido tudo assim, assíncro. O Nuswit já vai fazer aniversário de 1 ano, e vale lembrar que está em produção contínua, sem dar nenhuma manutenção.

Já estou mais que convencido que o caminho pros próximos anos dessa década não pode ser outro, ainda mais com o WebSocket no w3c.

Para contribuir com a interwebs, tenho mantido os seguintes projetos:

http://github.com/fiorix/cyclone
Um clone do Tornado, webserver assíncrono do FriendFeed, que desde o ano passado é do Facebook. Essa implementação, batizada de Cyclone, tem algumas diferenças:

  • Core I/O baseado no Twisted
  • Suporte nativo a XMLRPC
  • Suporte a localização baseada no gettext – ao invés do CSV, original do Tornado

Com vários aplicativos de exemplos, todos os plug-ins do Tornado para autenticação no Google, Twitter, Facebook, OAuth, OpenID, etc…

O RestMQ (coisas do Gleicon, que ajudei a implementar) é baseado nele. A nova versão do Nuswit também será.

http://github.com/fiorix/twisted-twitter-stream
Uma API bem simples para acessar a Streaming API do Twitter. Provê suporte a todos os métodos publicados pela API.

Não depende do TwistedWeb, a implementação do HTTP 1.1 está inteira no código – na verdade, apenas o lado do client com suporte a Comet.

Permite criar sistemas como este.

http://github.com/fiorix/txredisapi
Um driver assíncrono pro Redis, também baseado no Twisted. O protocolo de comunicação já existia, mas era carente de algumas coisas, que implementei:

Além de estável, é muito rápido! Também foi usado no RestMQ, e aparentemente, está se tornando popular. Hoje achei algumas referências enquanto procurava no Google.

http://github.com/fiorix/mongo-async-python-driver
Outro driver de banco de dados, pro MongoDB. O driver original para Python é síncrono, o que dificulta (embora não impossibilita) de usar em sistemas assíncronos, especialmente baseados no Twisted.

Boa parte da implementação é baseada no pymongo original, inclusive o codec de BSON (em C), formato binário usado pelo Mongo, baseado em JSON.

Provavelmente se tornará o driver assíncrono oficial do Mongo para Python+Twisted, e está em vias de se tornar estável – isso devido às várias mudanças na API, e implementação de vários recursos incluindo Lazy Connections, e Document Reference.

Também, já tem algumas pessoas de olho no GitHub, acompanhando o desenvolvimento.

Entre os vários dbs nosql (couch, redis, etc) o Mongo é um dos mais completos, com uma linguagem de query muito decente, entre os vários outros recursos nativos. O fato de usar mmap para acessar os dados também faz com que ele seja muito rápido.


skype no iphone 3g

skype-logoDepois de tanto tempo sem escrever nada, volto logo com uma boa: fazer chamadas de voz por SIP ou Skype, no iPhone, usando a rede 3G !

Aproveitando o assunto (iPhone), vale lembrar que tem apenas duas coisas que me irritam profundamente (até agora) com este telefone:

  1. Não permitir SIP/VoIP/Skype pela rede 3G (olho gordo das operadoras)
  2. Não ter suporte a Flash (idiotice da Apple por causa dos jogos)

De resto, pra quem curte Interweb, é o melhor aparelho que existe.

Voltando ao assunto… a primeira coisa necessária pra ignorar as restrições de SIP/VoIP/Skype apenas pela conexão WiFi é fazer o jailbreak do telefone. O melhor programa que encontrei pra fazer isso, à partir do Mac OS X, é o PwnageTool – não sei o que tem pra Linux nem Windows, não me xinguem.

O jailbreak irá instalar o Cydia automaticamente, que é um front-end pro APT, exatamente igual ao do Debian.

Depois disso é necessário conectar o iPhone a uma rede WiFi, saber o endereço IP dele, e pelo Cydia, instalar os pacotes OpenSSH, APT7 (Strict) e Bigboss Recommended Tools (este irá prover tudo que interessa: ps, vim, etc…).

Com isso feito, você precisa conectar via SSH no iPhone, usando o seu programa preferido: ssh no console, ou PuTTY pros usuários de Windows. Pra conectar no iPhone, o usuário é root e a senha padrão é alpine.

No console, é necessário instalar dois pacotes:

  • mobilesubstrate : resumindo, insere código em um app durante sua execução
  • voipoverip3g: biblioteca do mobilesubstrate pra enganar o iPhone, assim os programar não sabem que estão usando 3G, e pensam que é WiFi (duh!)

Para instalar, o procedimento é padrão de debian/ubuntu, mas no console do iPhone:

apt-get install mobilesubstrate voipoverip3g

Com isso feito, reinicie o iPhone, re-instale o Skype, e seja feliz. Quando abrir o Skype pela primeira vez, ele vai reclamar que “não foi feito pra rodar em iPhoneOS modificado”, mas é “apenas uma mensagem”.

Pros mais interessados: o pacote voipoverip3g instala esse “plugin” pro mobilesubtrate, e sua configuração fica em

/Library/MobileSubstrate/DynamicLibraries/VoIPover3G.plist

Você pode adicionar suporte a qualquer programa que seja restrito ao uso de SIP/VoIP pela rede WiFi, basta editar com vim e adicionar a chave do programa, seguindo o formato do arquivo. O padrão é adicionar suporte ao Fring e Skype.

Este é o conteúdo original do arquivo:

Bozo:~ root# cat /Library/MobileSubstrate/DynamicLibraries/VoIPover3G.plist
Filter = {Bundles = ("com.Fringland.Fring", "com.skype.skype");};

Boa?


freeswitch, eventsocket, twisted!

freeswitchApós meses tentando resolver problemas ridículos com meu discador automático baseado em Asterisk, acabei mudando totalmente o rumo do sistema e re-escrevi todo o código para o FreeSWITCH.

A versão anterior se conectava no manager do Asterisk, originava as chamadas, e naquela completa bagunça sem padrão ia controlando o fluxo da chamada com auxílio de um AGI. Funções como transferência e gravação com detecção de caixa postal geravam diversas complicações devido à maneira como o Asterisk funciona, e o resultado era muita dor de cabeça.

Agora, a bagunça é assíncrona, tem padrão, e controla totalmente o FreeSWITCH através do Event Socket. Ao se conectar no Inbound Socket, o sistema origina as chamadas com destino ao Outbound Socket, onde cada uma é controlada individualmente e todos recursos funcionam perfeitamente, inclusive as várias maneiras de realizar transferência (bridge).

O FreeSWITCH está próximo da perfeição no quesito funcionamento, pecando apenas na documentação e alguns detalhes relacionados ao retorno (erro, etc) na originação de chamadas. Porém, esses detalhes são totalmente contornáveis com soluções simples, sem gambiarras e maracutaias como era com o Asterisk.

Em uma máquina comum, consigo manter 60 ligações simultâneas consumindo apenas 3% de cpu time. E o FreeSWITCH, que faz todo o controle das chamadas – conversão de mídia, gravação, detecção de caixa postal, de fax, etc etc etc, consome apenas 30% de cpu time.

Tudo isso é feito usando um protocolo do Twisted pro Event Socket do FreeSWITCH, que escrevi no último final de semana – entre carnaval, rock, etc. E pra felicidade geral da nação, tornei público pela lisença GPLv2, disponível no Google Code com exemplos.


asterisk mfc/r2 (unicall VS placas nacionais)

O asterisk é meia boca, e todo mundo sabe. Tem zilhões de bugs, erros no código, problemas de design (é, não se assuste, mas ele foi mal projetado), etc etc etc. Porém, com alguns truques na configuração é possível deixá-lo estável pra ambientes específicos – especialmente quando se trata de links E1.

As placas importadas – pelo menos Digium e Sangoma (melhor opção) – não oferecem suporte nativo ao protocolo de sinalização mais comum aqui do Brasil, que é o MFC/R2. Nesse caso, pra usar essas placas é necessário compilar o unicall, que oferece esse suporte por meio de software.

No voip-info há uma página inteira só com informações sobre como instalar e usar links com sinalização MFC/R2 com placas digium. É relativamente simples, porém o unicall é relativamente instável e tem vários dead locks aleatórios, que muitas vezes não são possíveis reproduzir pra testar e achar uma solução.

A alternativa é usar placas nacionais, como as da Digivoice ou da Khomp. Além disso, essas empresas fabricam outros produtos muitos interessantes como placas PCI com interface celular – que você coloca os chips GSM e usa a linha direto pelo asterisk – e também as interfaces FXS/FXO. A Digivoice tem um produto muito interessante, que é o Channel Bank 3000, pra multiplexar diversas linhas ou aparelhos de telefone analógicos / fax em um link E1 MFC/R2.

Depois de testar tudo isso, quebrar a cabeça e passar várias madrugadas recompilando coisas, cheguei à seguinte conclusão: a mais simples, mais estável e melhor das placas pra usar E1 com asterisk é a Khomp.

Apesar dos problemas no programa de configuração da placa com unicode no Debian e Ubuntu – parece que resolveram na última versão – essa placa é boa e o software também. Quando me refiro ao software, falo do módulo do kernel, programa de configuração bem completo com todas as opções possíveis e imagináveis do link MFC/R2, canal do asterisk, e esquema de debug.

Nesse conjunto, do meu ponto de vista, a Khomp supera todos os outros.

Quando comparada aos produtos importados:

  1. Não precisa usar unicall;
  2. Suporte local por telefone e email;
  3. Pra ter o unicall funcionando, precisa ter até libtiff (xlib, ugh) na máquina!

A Digivoice não é ruim, porém o software é um problema. A filosofia deles é melhor que da Khomp, pois ao adquirir uma placa eles dão o source code do módulo e do canal do asterisk, enquanto a Khomp dá um self-extractor sujo feito em bash com tudo binário – mas se você pedir com jeito no suporte, eles dão os fontes pelo menos do módulo do kernel.

O que encontrei com os módulos da Digivoice:

  1. Problemas do módulo com SMP;
  2. Eles sugerem desligar o ACPI – não funcionou pra mim / ubuntu gutsy default kernel
  3. Depois de desligar o ACPI (com SMP), colocar só o módulo da placa no CPU1 e todo o resto no CPU0 – com echo 2 > /proc/irq/NN/smp_affinity. Não muda muita coisa;
  4. Ao remover o módulo, rola um dump no kernel e só volta a funcionar depois de reiniciar a máquina;
  5. Qualquer reboot ou halt gera outro dump no kernel e só desliga no botão;
  6. Em load médio (60 canais simultâneos), todos os canais do asterisk travam e só voltam depois de reiniciar o serviço.

Enfim, são problemas que aparentemente estão relacionados ao código do módulo, que do meu ponto de vista é mau feito. Fora isso, em algumas máquinas – tipo ProLiant HP e alguns IBM – a placa some após algum reboot, e só volta a aparecer (inclusive no lspci, dmidecode) após trocá-la de slot PCI.

Isso também já aconteceu com a Khomp, e com outras placas nacionais de captura de imagem/tv. Não sei exatamente o que é, mas só vi isso na vida com placas nacionais, nunca com as importadas.

O fato é que pra quem não quer saber de compilar kernel, e nem usar fedora – tudo Debian e Ubuntu, a Khomp é muita moleza. Dois comandos e o asterisk tá no ar com ela.

Mas não pense que a placa irá resolver os problemas do asterisk, porque tem muito mais coisa envolvida nisso.

Tem mesmo que ser muito malandro pra ter um asterisk estável. Usar uma placa pra E1 que elimina parte dos problemas já é um bom começo.


o que é freeswitch?

O FreeSWITCH é um soft-switch modular, escrito em C e licenciado sob a Mozilla Public License. Ele surge como uma alternativa viável para a maioria das necessidades em aplicações de voz, desde roteamento de sinalização SIP e mídia RTP ou SRTP, até URAs e fácil integração com aplicações externas.

Apesar das versões preliminares serem utilizadas em alguns ambientes de produção, com vazão de 300 chamadas por segundo, poderemos utilizá-lo com mais segunraça a partir do dia 26 de maio, quando será lançada sua versão 1.0.

Já existem alguns bindings da API do FreeSWITCH para algumas linguagens, como: Python, Java, Perl, Lua, Javascript; além de alguns frameworks que se conectam ao Event Socket e exportam funções para o disparo e controle de chamadas. Em ambos os casos, a abstração esperada é alcançada.

A arquitetura do FreeSWITCH foi cuidadosamente montada para evitar deadlocks, race conditions e todos os outros problemas enfrentados por usuários e programadores do Asterisk. Outra diferença para o Asterisk, é que o núcleo (core) do FreeSWITCH é consistente e não depende de módulos externos. O núcleo não deveria, nunca, depender de módulos externos, porém o do Asterisk depende.

Tudo isso se traduz em aprender com os erros e escrever software que trabalhe conosco, não contra nós. O core é orientado por uma máquina de estados, que controla o estado de cada nova sessão (ou chamada) criada. A cada transição de estado, um evento é gerado. Qualquer módulo pode registrar event handlers que são chamados quando determinados eventos são gerados. Inclusive, é possível que existam diversos event handlers pra um determinado evento. A propagação do mesmo se dará até que um dos event handlers chamados retorne SWITCH_STATUS_FALSE.

Toda essa coerência torna desnecessário os hacks para alcançar os objetivos de um soft-switch moderno, além de tornar o FreeSWITCH uma plataforma de desenvolvimento – mas não pára por aí.

Por padrão, o software lê suas configurações a partir de arquivos XML, mas qualquer módulo poderia ser o responsável por requisitar e interpretar as configurações. Uma estratégia interessante, é utilizar o mod_xml_curl, que já faz parte do FreeSWITCH, para solicitar todas as configurações via HTTP, ao invés de ler arquivos XML do disco.

Assim, poderia existir um servidor de configuração, que rodaria um webserver, um banco de dados e alguma linguagem de scripting ou um CGI. Poderiam existir 10 servidores com FreeSWITCH rodando, que executariam GETs no servidor de configuração, que entregaria a opção desejada.

Arquitetura simples, com configuração centralizada e desempenho escalonável: se uma expansão for necessária, é só adicionar mais um servidor com FreeSWITCH, igual aos outros já existentes. As configurações que podem ser puxadas remotamente não se limitam à adição e exclusão de usuários, mas a toda e qualquer opção configurável do software. Isso inclui o dialplan, que é flexível o suficiente para tomar decisões não apenas baseado em extension matching, mas também em endereços de rede, variáveis do canal, dados do usuário, etc., o que torna o esquema todo muito flexível.

  • Protocolos VoIP suportados: SIP, IAX e Jinggle
  • TDM: Linhas analógicas (FXS e FXO) e ISDN PRI
  • Codecs: G.711, G.722 (passthru), G.723.1 (passthru), G.726, G.729 (passthru), AMR (passthru), iLBC, Speex, lpc10 e DVI4.
Suporte para MFC/R2, amplamente utilizado no Brasil, está sendo escrito. Desta forma, poderemos utilizar os benefícios de uma plataforma VoIP livre e confiável.
Links, todos com conteúdo em inglês: