How to get rid of unkillable Freeswitch channels - python

After upgrading from Freeswitch 1.2.9 (1.2.9+git~20130506T233047Z~7c88f35451) to Freeswitch 1.4.21 (1.4.21-35~64bit), freeswitch stopped dropping channels after they were hung up, and when we tried to do a manual uuid_kill, it gives us this lovely error:
-ERR No such channel!
Even though show channels shows that channel clearly there. From the bugs on jira.freeswitch.com that I've seen, it looks like it may be a code problem. A little more info on our environment/code:
We have a python twisted loop that connects to the client so the client can run commands on the server and vice versa. As soon as that twisted connection dies (the client is closed/disconnected) the channels are killed as well, but we need the channel to die before then as we're taking a lot of calls per second and need them to die when the other end is disconnected. We can't close and reopen the client every time a call is done, or reconnect as that would take way too much time and defeats the purpose of our use of the software.
Once again, this error only started happening when we changed to installing the freeswitch server using apt-get instead of directly from source. This lets us get a new server up and running extremely faster, and we would rather not take the extra time to use our previous method. Please tell me if there's any code you would like to look at, and ask for any clarification you need, but we would really like this to be fixed soon. Thanks in advance!
Edit: For more clarification, we're mainly using mod_callcenter, mod_conference, and mod_sofia with our software.
Edit 2: For a little more clarification, we're running this on Ubuntu 14.04 Server
We are using an ESL connection to connect and run commands in freeswitch from python, and we think that's the root of the problem. We tried exiting the connection, but that destroys both channels.
Also, all of the bugs filed already for this problem on Jira are closed for not being bugs. I thought I may have a bit more success here, as it is a programming type question.

You need to reproduce the issue in a test environment and file the bug report to Jira. At best you should also try reproducing it with the latest master branch (only Debian 8 is supported):
https://freeswitch.org/confluence/display/FREESWITCH/Debian+8+Jessie
I had a similar problem when I used mod_perl, and a Perl object was referring to a session, and it was not properly destructed (if I remember it right, I had two Perl objects attached to the same session). That resulted in channels which were impossible to kill.
I suppose you are using a ESL connection between your application and FreeSWITCH, right?

Related

What is needed to refactor this Twisted code for Python3.6?

Having trouble figuring out how to refactor some code written for Twisted under Python2.7 for Python3.6
I have been trying to figure out how to get the repository at https://github.com/stylesuxx/udp-hole-punching to work on Python3.6, using the Twisted library. According to the Readme, Python2.7 is required, although Twisted should work on Python3.5+. This leads me to believe that the problem is with the repository itself, although I can't figure out what to change.
I have run the code under Python2.7, and it works. The client and server will connect, and will output messages showing what connections are being made. Under Python3.5, however, no messages at all are output, and it essentially appears that nothing is happening at all. No error messages are displayed.
You might want to start with syntax changes, which your IDE if you use one should be highlighting, like changing print statements from
print 'text'
to
print('text')
See this cheat sheet and Porting Python 2 Code to Python 3 for more information.
Ok, I think I have the answer. I found this page: https://twisted.readthedocs.io/en/twisted-16.6.0/core/howto/python3.html.
I found the lines in server.py which started with "self.transport.write" and sent the message as bytes, rather than strings, by using an initial b or .encode(). I also changed the line if datagram == '0' to if datagram == b'0'.
Seems to be working so far. If I hit any more obstacles I will share it here.

Can't play a note with mingus

I've came to use mingus to try to reproduce some notes in python. Based on what was answered here, I've tried with:
from mingus.midi import fluidsynth
fluidsynth.init('/home/btc/Escritorio/SinestesiaRCB/gfx/ViolinsLong.sf2',"alsa")
fluidsynth.play_Note(64,0,100)
#Also tried with Note("C-5") and so forth
Using among others, one of this sf2 files. But then I got the error:
fluidsynth: warning: Failed to set thread to high priority
fluidsynth: warning: No preset found on channel 9 [bank=128 prog=0]
Researching a bit, this answer said:
For General MIDI compatibility, the default sound font instrument
assignments are bank 0, program 0 ("Acoustic Grand Piano") for
channels 0–8 and 10–15, and bank 128, program 0 ("Default Drum Set")
for channel 9. Apparently, your sound font does not have the latter.
This does not matter if your MIDI file does not assume General MIDI
compatible instruments and does not try to play drum sounds on channel
9.
But aside of this, that may made things a bit clearer, I still don't know how to solve it.
Plus, if I use the same file that the answer of the very first link, then the error I get is this one (and don't know how to solve it neither):
fluidsynth: warning: Failed to set thread to high priority
fluidsynth: warning: Failed to pin the sample data to RAM; swapping is possible.
Update
Running the program with sudo permissions removes this errors, but it doesn't sound. This way, the error I get is:
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-root'
I thought it may be a problem with the selected driver mode in fluidsynth driver, but I've tried with them all (alsa, oss, and so forth) with the same result. Just for the sake of completeness, I'm running it within a VM, and other sounds inside it are correctly reproduced in my host speakers.
However based on this answer, I guess it should be solved by passing to it the right sound environment variable. Which I don't know. I've tried with:
pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY python3 /home/btc/Escritorio/SinestesiaRCB/SinestesiaRCB.py
Where the complete path to the file is needed since this needs sudo permissions and changes its working directory, and in the end the same error came: XDG_RUNTIME_DIR.
Update 2
If I run it with sudo -E option, the error is replaced by a new one:
QStandardPaths: wrong ownership on runtime directory /run/user/1000, 1000 instead of 0
I'm reading in some webs, that the 1000 user is supposed to be the default user instead of root.
Therefore, I've done a:
sudo chown root:root /run/user/1000
Just to try, and then the app runs without fails, but it still doesn't sound.
Update 3
Based on this example and this Q&A, I've tried both to use time sleep with several times, and using raw_input as well after (also before) doing a play_note, but it still doesn't sound.
I'll answer my own question, but the very big part of the debug/solving process is in the question itself done with updates.
The last part was to get it to sound, when not even waiting with sleep was making it work. Not even doing it before and after the play_note function. May I say that this function always returned True, so the note was expected to sound from the very beginning. The thing is, that the SF2 file (almost 150MB) was loaded successfully, or at least it seemed like it, since it returned True as well and was for sure pretty fast.
The solution
Let's continue after reaching the point where no errors were printed when executing my script (just before Update 3 in the Question).
I wanted to check how much CPU percent usage was doing my script, so I used top on my Linux terminal and found pulseaudio running from several days ago:
Killing this process allowed it to sound finally. However, I must say that a time.sleep() with about 0.25 seconds was added after the play_Note() function, in order to let it play the note completely.

Where do messages go when using pythoncom.PumpMessages()?

I would like to know where does the function pythoncom.PumpMessage() stores the message when it comes into play. I was going through a site and just saw a Python Script for Key logger, I copied the code and used it on my computer but I don't feel safe, after deleting that code I think it's still running in the background and copying my keypresses. Is it so, please help.
If the python script was sending messages to anyone, you'd probably be able to tell by looking at the code. Somewhere there would be a block of code sending some file to a server.
As for PumpMessages(), it
Pumps all messages for the current thread until a WM_QUIT message.
According to this documentation. You can find other answered questions on this with a Google search as well. Pythoncom isn't sending any information to an external source in and of itself, however your script might be. You'd have to check your code for a block doing that.
As for it running after you delete the script, highly unlikely. If you didn't manually or programmatically (in the script) attach the Python script to some daemon, it isn't manifesting itself anywhere. You may be over-estimating the power of a basic Python keylogger. I wouldn't worry.
I've tried keyloggers before with pythoncom, and I've never had a problem. You can also look in the pythoncom library to find the PumpMessages() function and see if that is sending anything.

Pyserial - Embedded Systems

I am not expecting a code here, but rather to pick up on knowledge of the folks out there.
I have a python code - which uses pyserial for serial communication with an Micro Controller Unit(MCU). My MCU is 128byte RAM and has internal memory. I use ser.write command to write to the MCU and MCU responds with data - I read it using ser.read command.
The question here is - It is working excellently until last week. Since yesterday - I am able to do the serial communication only in the morning of the day. After a while, when I read the data the MCU responds with"NONE" message. I read the data next day, it works fine. Strange thing is - I have Hyperterminal installed and it properly communicates with the MCU and reads the data. So I was hoping if anyone have faced this problem before.
I am using threads in my python program - Just to check if running the program mulitple times with threads is causing the problem. To my knowledge, threads should only effect the Memory of my PC and not the MCU.
I rebooted my Computer and also the MCU and I still have this problem.
Note: Pycharm is giving me the answers I mentioned in the question. If I do the same thing in IDLE - it is giving me completely different answers
So, ultimately you're looking for advice on how to debug this sort of time dependent problem.
Somehow, state is getting created somewhere in your computer, your python process, or the microcontroller that affects things. (It's also theoretically possible that an external environmental factor is affecting things. As an example, if your microcontroller has a realtime clock, you could actually have a time-of-day dependent bug. That seems less likely than other possibilities).
First, try restarting your python program. If that fixes things, then you know some state is created inside python or your program that causes the problem.
Update your question with this information.
If that doesn't fix it, try rebooting your computer. If that fixes things, then you strongly suspect some state in your computer is affecting things.
If none of that works, try rebooting the micro controller. If rebooting both the PC and the micro controller doesn't fix things, include that in your question as it is very interesting data.
Examples of state that can get created:
flow control. The micro controller could be sending xoff, clearing clear-to-send or otherwise indicating it does not want data
Flow control in the other direction: your PC could be sending xoff, clearing request-to-send or otherwise indicating that it doesn't want data
Your program gets pyserial into a confused state--either because of a bug in your code or pyserial.
Serial port configuration--the serial port settings could be getting messed up.
Hyper terminal could do various things to clear flow control state or reconfigure the serial port.
If restarting python doesn't fix the problem, threading is very unlikely to be your issue. If restarting python fixes the problem threading may be an issue.

Python Libraries for FTP Upload/Download?

Okay so a bit of forward:
We have a service/daemon written in python that monitors remote ftp sites. These sites are not under our command, some of them we do NOT have del/rename/write access, some also are running extremely old ftp software. Such that certain commands do not work. There is no standardization among any of these ftp's, and they are out of our control(government).
About a year ago i wrote a ftp wrapper library for in house that basically adds in stuff like resume upload/resume download/verifying files are not currently being written to, etc. The problem is we soon found out is that due to so many of the ftp servers running werid/non standard software we were constantly fighting with the wrapper library/ftplib.
Basically I've given up on ftplib. Is there an alternative? I've looked at most of the ftp alternatives all of them are missing one or another key component of functionality.
What ever the choice is, it must run for python 2.5.2 (we cannot change). and must run on Linux/Windows/HP-UX.
Update:
Sorry i forgot to tell you alternatives i looked at:
ftputil, problem is it does not support resume upload/download and stuff like partially downloading files given an offset.
Pycurl looked good, i'll look at it again.
You don't mention which alternatives you've looked at already. Is ftputil one of them?
http://ftputil.sschwarzer.net/trac/wiki/Documentation
If you're trying to code around edge cases from various server implementations, you might be better off looking at the code used by Mozilla/Firefox. I imagine this is one of the things they have to deal with constantly.
You may have better luck with one of the cURL bindings such as pycURL.

Categories