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.
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.
strace -f asterisk 2>&1 | grep write | grep AT [pid 14715] write(17, "AT\r", 3 <unfinished ...> [pid 14715] write(17, "ATZ\r", 4) = 4 [pid 14715] write(17, "ATE0\r", 5) = 5 [pid 14715] write(17, "AT+CGMI\r", 8) = 8 [pid 14715] write(17, "AT+CGMM\r", 8) = 8 [pid 14715] write(17, "AT+CGMR\r", 8) = 8 [pid 14715] write(17, "AT+CMEE=0\r", 10) = 10 [pid 14715] write(17, "AT+CGSN\r", 8) = 8 [pid 14715] write(17, "AT+CIMI\r", 8) = 8 [pid 14715] write(17, "AT+CPIN?\r", 9) = 9 [pid 14715] write(17, "AT+COPS=0,0\r", 12) = 12 [pid 14715] write(17, "AT+CREG=2\r", 10 <unfinished ...> [pid 14715] write(17, "AT+CREG?\r", 9) = 9 [pid 14715] write(17, "AT+CNUM\r", 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,1\r", 12) = 12 [pid 14715] write(17, "AT+CMGF=0\r", 10) = 10 [pid 14715] write(17, "AT+CSCS=\"UCS2\"\r", 15) = 15
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.
$ /answering_machine /dev/ttyUSB0 /dev/ttyUSB1 /home/carlos/rec.raw
- 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).