Git Product home page Git Product logo

drachtio-freeswitch-modules's Introduction

Please note: This repo is no longer being actively maintained.

For those interested in similar modules, please refer to this repo which is offered under a different (dual-licensing) scheme:

  • AGLP-3 for general usage.
  • MIT for use with jambonz installs only.

drachtio-freeswitch-modules

An open-source collection of freeswitch modules, primarily built for for use with drachtio applications utilizing drachtio-fsrmf, but generally usable and useful with generic freeswitch applications. These modules have beeen tested with Freeswitch version 1.8.

A Freeswitch module that attaches a bug to a media server endpoint and streams L16 audio via websockets to a remote server. The audio is never stored to disk locally on the media server, making it ideal for "no data at rest" type of applications. This module also supports receiving media from the server to play back to the caller, enabling the creation of full-fledged IVR or dialog-type applications.

A tts provider module that integrates with Google Cloud Text-to-Speech API and integrates into freeswitch's TTS framework (i.e., usable with the mod_dptools 'speak' application)

Adds a Freeswitch API call to start (or stop) real-time transcription on a Freeswitch channel using Google Cloud Speech-to-Text API.

Adds a Freeswitch API to start a Google Dialogflow agent on a Freeswitch channel.

Adds Freeswitch APIs call to integrate with aws lex v2 apis.

Adds a Freeswitch API call to start (or stop) real-time transcription on a Freeswitch channel using AWS streaming transcription (HTTP/2 based).

Installation

These modules have dependencies that require a custom version of freeswitch to be built that has support for grpc (if any of the google modules are built) and libwebsockets. Specifically, mod_google_tts, mod_google_transcribe and mod_dialogflow require grpc, and mod_audio_fork requires libwebsockets.

Building from source

This ansible role can be used to build a freeswitch 1.8 with support for these modules. Even if you don't want to use ansible for some reason, the task files, and the patchfiles should let you work out how to build it yourself manually or through your preferred automation (but why not just use ansible!)

Note: that ansible role assumes you are building on Debian 9 (stretch).

Using docker

docker pull drachtio/drachtio-freeswitch-mrf:v1.10.1-full to get a docker image containing all of the above modules with the exception of mod_aws_transcribe.

Configuring

The three modules that access google services (mod_google_tts, mod_google_transcribe, and mod_dialogflow) require a JSON service key file to be installed on the Freeswitch server, and the environment variable named "GOOGLE_APPLICATION_CREDENTIALS" must point to that file location.

drachtio-freeswitch-modules's People

Contributors

ak-army avatar byoungdale avatar carolinasolfernandez avatar davehorton avatar dependabot[bot] avatar entenschnabel avatar eschmidbauer avatar goddva avatar hhadzem avatar hunyadvari-peter avatar manum avatar pragmatrix avatar ruipfmendes avatar stevetodd avatar telmojsneves avatar vcc-core avatar vinoddh-kore avatar xquanluu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

drachtio-freeswitch-modules's Issues

Broken query parameters for 'listen' verb url

I am passing a JWT as a query parameter in the url for the 'listen' verb, and I receive it broken in the socket server

What I send as socket address:

wss://public.wss.url/calls?access_token=eyJraWQiOiJrTWZYMVdvRGM5ZFdWUnVnd0doOXNTTDk1NkpTN3lCOGpFMXlsbzcxWi1NIiwiYWxnIjoiRWREU0EifQ.eyJyZWZyZXNoU2Vzc2lvbiI6ZmFsc2UsImxhbmd1YWdlIjp7Imxhbmd1YWdlSWQiOiIxIiwiaXNvMkNvZGUiOiJlbiIsIm5hbWUiOiJFbmdsaXNoIiwibG9jYWxlIjoiZW5fR0IifSwiY2hlY2tTZXNzaW9uIjpmYWxzZSwidHlwIjoiQmVhcmVyIiwic2VzIjoiYjMzNDA5NDgtNmI4Zi00NzJkLWIzMGItNGVmYmJkMDU1YmZmIiwicGVyIjoiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBPSIsInN1YiI6IjEyMTgiLCJhdWQiOiJ1dC1idXMiLCJpc3MiOiJ1dC1sb2dpbiIsImlhdCI6MTYzNzA2NTQzOCwiZXhwIjoxNjM3MDY2MzM4fQ.71s6uLLJctmZWFZGx7hlaCdQfwaaWRmBy-3swxLFiU_rDY2ZWbgNGAHYHElIyRIOt9ZCj6o1QxYLnhbpKcwPBw

Address that gets called:

wss://public.wss.url/calls?access_token=eyJraWQiOiJrTWZYMVdvRGM5ZFdWUnVnd0doOXNTTDk1NkpTN3lCOGpFMXlsbzcxWi1NIiwiYWxnIjoiRWREU0EifQ.eyJyZWZyZXNoU2Vzcpublic.wss.url

[unable to load mod_audio_fork][FreeSWITCH 1.10]

Hi,
I am trying to test mod_audio_fork under FreeSWITCH 1.10, after the module is build i am trying to load that in freeswitch but getting following error

2020-03-07 09:03:51.161248 [CRIT] switch_loadable_module.c:1786 Error Loading module /usr/local/freeswitch/mod/mod_audio_fork.so
/usr/local/freeswitch/mod/mod_audio_fork.so: undefined symbol: parse_ws_uri

Can you please help me what i am doing wrong here.

Regards
Abbasi

[mod_google_transcribe]: Freeswitch crash while ending google transcription

Code base is latest but with line numbers would not be exactly same.
gdb backtrace:

(gdb) bt
#0 writesDone (this=0x0) at google_glue.cpp:143
#1 google_speech_session_cleanup (session=0x7f8758a4c5b8, channelIsClosing=1) at google_glue.cpp:398
#2 0x00007f8779581f8c in capture_callback (bug=0x7f86880d1068, user_data=0x7f8688005c70, type=SWITCH_ABC_TYPE_CLOSE) at mod_google_transcribe.c:65
#3 0x00007f87811cebbd in switch_core_media_bug_close (bug=0x7f8664432b48, destroy=SWITCH_FALSE) at src/switch_core_media_bug.c:1263
#4 0x00007f87811ceeb1 in switch_core_media_bug_remove_all_function (session=0x7f8758a4c5b8, function=0x0) at src/switch_core_media_bug.c:1231
#5 0x00007f87811eb1a9 in switch_core_session_hangup_state (session=0x7f8758a4c5b8, force=SWITCH_TRUE) at src/switch_core_state_machine.c:839
#6 0x00007f87811ecccd in switch_core_session_run (session=0x7f8758a4c5b8) at src/switch_core_state_machine.c:616
#7 0x00007f87811e6fce in switch_core_session_thread (thread=, obj=0x7f8758a4c5b8) at src/switch_core_session.c:1709
#8 0x00007f87811e2a1d in switch_core_session_thread_pool_worker (thread=0x7f86873dcdc0, obj=0x80) at src/switch_core_session.c:1772
#9 0x00007f87816e28e0 in dummy_worker (opaque=0x7f86873dcdc0) at threadproc/unix/thread.c:151
#10 0x00007f87806ad064 in start_thread (arg=0x7f8664433700) at pthread_create.c:309
#11 0x00007f877fd8462d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
(gdb) bt full
#0 writesDone (this=0x0) at google_glue.cpp:143
No locals.
#1 google_speech_session_cleanup (session=0x7f8758a4c5b8, channelIsClosing=1) at google_glue.cpp:398
cb = 0x7f8688005c70
streamer = 0x0
st = SWITCH_STATUS_SUCCESS
channel = 0x7f8758c23250
time_elapsed = 0
var =
final_voice_duration = 0x0
func = "google_speech_session_cleanup"
bug = 0x7f86880d1068
speech_executions = 0
voice_duration =
#2 0x00007f8779581f8c in capture_callback (bug=0x7f86880d1068, user_data=0x7f8688005c70, type=SWITCH_ABC_TYPE_CLOSE) at mod_google_transcribe.c:65
session = 0x7f8758a4c5b8
#3 0x00007f87811cebbd in switch_core_media_bug_close (bug=0x7f8664432b48, destroy=SWITCH_FALSE) at src/switch_core_media_bug.c:1263
bp = 0x7f86880d1068
func = "switch_core_media_bug_close"
#4 0x00007f87811ceeb1 in switch_core_media_bug_remove_all_function (session=0x7f8758a4c5b8, function=0x0) at src/switch_core_media_bug.c:1231
bp = 0x7f86880d1068
status = 2282557544
func = "switch_core_media_bug_remove_all_function"
#5 0x00007f87811eb1a9 in switch_core_session_hangup_state (session=0x7f8758a4c5b8, force=SWITCH_TRUE) at src/switch_core_state_machine.c:839
cause = SWITCH_CAUSE_NORMAL_UNSPECIFIED
cause_q850 = SWITCH_CAUSE_NORMAL_UNSPECIFIED
proceed = 31
global_proceed = 31
midstate = CS_HANGUP
endpoint_interface = 0x0
driver_state_handler = 0x7f87790ad080 <sofia_event_handlers>
hook_var = 0x1 <error: Cannot access memory at address 0x1>
use_session = 0
func = "switch_core_session_hangup_state"
PRETTY_FUNCTION = "switch_core_session_hangup_state"
#6 0x00007f87811ecccd in switch_core_session_run (session=0x7f8758a4c5b8) at src/switch_core_state_machine.c:616
ptr = 0x0
midstate = CS_HANGUP
endstate = CS_NEW
endpoint_interface = 0x0
driver_state_handler = 0x7f87790ad080 <sofia_event_handlers>
PRETTY_FUNCTION = "switch_core_session_run"
func = "switch_core_session_run"
#7 0x00007f87811e6fce in switch_core_session_thread (thread=, obj=0x7f8758a4c5b8) at src/switch_core_session.c:1709
session = 0x7f8758a4c5b8
event = 0x4c4b40
event_str = 0x0
---Type to continue, or q to quit---
val =
func = "switch_core_session_thread"
PRETTY_FUNCTION = "switch_core_session_thread"
#8 0x00007f87811e2a1d in switch_core_session_thread_pool_worker (thread=0x7f86873dcdc0, obj=0x80) at src/switch_core_session.c:1772
td = 0x7f875921a760
pop = 0x7f875921a760
check_status = 1495377760
pool = 0x7f86873dcb68
func = "switch_core_session_thread_pool_worker"
#9 0x00007f87816e28e0 in dummy_worker (opaque=0x7f86873dcdc0) at threadproc/unix/thread.c:151
thread = 0x7f86873dcdc0
#10 0x00007f87806ad064 in start_thread (arg=0x7f8664433700) at pthread_create.c:309
__res =
pd = 0x7f8664433700
now =
unwind_buf = {cancel_jmp_buf = {{jmp_buf = {140215184471808, 817260727955083411, 0, 140217799025520, 20, 140215184471808, -838875922313260909, -839782135128010605},
mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 0}}}
not_first_call =
pagesize_m1 =
sp =
freesize =
PRETTY_FUNCTION = "start_thread"
#11 0x00007f877fd8462d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
No locals.

mod_google_tts and mod_google_transcribe stuck

Hello,

We are extremely grateful for your assistance on the last issue we had posted. We have successfully compiled and loaded both the modules for tts and transcription but we are facing a problem wherein we are able to hear a few words for the tts then it gets stuck as if the stream is getting blocked and also we tried transcription and we get no events for transcription and also after hangup freeswitch crashes.

Here is the freeswitch log, you can see we first do a tts followed by echo for testing the transcription but it gets stuck at tts and if we hangup we get this "2020-08-17 12:35:15.536285 [ERR] google_glue.cpp:183 grpc_read_thread: session 05de34e4-e086-11ea-80fc-05660e00bad8 is gone!" in the logs before the freeswitch crashes. We have also tried and tested both these modules separately but we face the same issue.

EXECUTE [depth=0] sofia/mgprofile/+917984662881 javascript(test.js)
2020-08-17 12:34:48.816291 [INFO] mod_google_transcribe.c:164 start transcribing en-IN complete
2020-08-17 12:34:48.916289 [INFO] mod_google_transcribe.c:59 Got SWITCH_ABC_TYPE_INIT.
2020-08-17 12:34:48.916289 [DEBUG] switch_core_media_bug.c:970 Attaching BUG to sofia/mgprofile/+917984662881
EXECUTE [depth=0] sofia/mgprofile/+917984662881 set(test=+OK Success
)
2020-08-17 12:34:48.916289 [DEBUG] mod_dptools.c:1672 SET sofia/mgprofile/+917984662881 [test]=[+OK Success
]
EXECUTE [depth=0] sofia/mgprofile/+917984662881 speak(google_tts|en-US-Wavenet-C|Hi there! This is an admittedly quite simple example of using google text to speech. Try it out for yourself some time, and do raise issues on github if you have any problems or suggestions. Ta for now!)
2020-08-17 12:34:48.916289 [DEBUG] mod_google_tts.c:36 speech_open - created file /tmp/0a2d7a6e-e086-11ea-8102-05660e00bad8.tmp.wav for name en-US-Wavenet-C, rate 8000
2020-08-17 12:34:48.916289 [DEBUG] switch_ivr_play_say.c:3023 OPEN TTS google_tts
2020-08-17 12:34:48.916289 [DEBUG] switch_ivr_play_say.c:3033 Raw Codec Activated
2020-08-17 12:34:48.916289 [DEBUG] mod_google_tts.c:61 speech_feed_tts
2020-08-17 12:34:48.916289 [INFO] google_glue.cpp:105 google_speech_feed_tts: synthesizing using voice: en-US-Wavenet-C, language: en-US: Hi there! This is an admittedly quite simple example of using google text to speech. Try it out for yourself some time, and do raise issues on github if you have any problems or suggestions. Ta for now!
2020-08-17 12:34:49.156288 [DEBUG] switch_ivr_play_say.c:2741 Speaking text: Hi there! This is an admittedly quite simple example of using google text to speech. Try it out for yourself some time, and do raise issues on github if you have any problems or suggestions. Ta for now!
2020-08-17 12:34:49.236358 [DEBUG] switch_rtp.c:7720 Correct audio ip/port confirmed.
2020-08-17 12:34:49.236358 [DEBUG] switch_core_io.c:448 Setting BUG Codec PCMU:0
2020-08-17 12:35:15.356290 [NOTICE] sofia.c:1084 Hangup sofia/mgprofile/+917984662881 [CS_EXECUTE] [NORMAL_CLEARING]
2020-08-17 12:35:15.356290 [DEBUG] switch_ivr_play_say.c:2905 done speaking text
2020-08-17 12:35:15.356290 [DEBUG] mod_google_tts.c:81 speech_flush_tts
2020-08-17 12:35:15.356290 [DEBUG] mod_google_tts.c:48 speech_close - closing file /tmp/0a2d7a6e-e086-11ea-8102-05660e00bad8.tmp.wav
2020-08-17 12:35:15.356290 [DEBUG] switch_core_session.c:2905 sofia/mgprofile/+917984662881 skip receive message [APPLICATION_EXEC_COMPLETE] (channel is hungup already)
EXECUTE [depth=0] sofia/mgprofile/+917984662881 echo()
2020-08-17 12:35:15.356290 [DEBUG] switch_core_session.c:2889 sofia/mgprofile/+917984662881 skip receive message [APPLICATION_EXEC] (channel is hungup already)
2020-08-17 12:35:15.356290 [DEBUG] switch_core_session.c:2905 sofia/mgprofile/+917984662881 skip receive message [APPLICATION_EXEC_COMPLETE] (channel is hungup already)
2020-08-17 12:35:15.356290 [INFO] mod_v8.cpp:925 Javascript result: [false]
2020-08-17 12:35:15.356290 [DEBUG] switch_core_session.c:2905 sofia/mgprofile/+917984662881 skip receive message [APPLICATION_EXEC_COMPLETE] (channel is hungup already)
2020-08-17 12:35:15.356290 [DEBUG] switch_core_state_machine.c:651 (sofia/mgprofile/+917984662881) State EXECUTE going to sleep
2020-08-17 12:35:15.356290 [DEBUG] switch_core_state_machine.c:585 (sofia/mgprofile/+917984662881) Running State Change CS_HANGUP (Cur 1 Tot 1)
2020-08-17 12:35:15.356290 [INFO] mod_google_transcribe.c:64 Got SWITCH_ABC_TYPE_CLOSE.
2020-08-17 12:35:15.356290 [INFO] google_glue.cpp:344 google_speech_session_cleanup: waiting for read thread to complete
2020-08-17 12:35:15.536285 [ERR] google_glue.cpp:183 grpc_read_thread: session 05de34e4-e086-11ea-80fc-05660e00bad8 is gone!

Could you please help us? Also please let us know what logs would be required for troubleshooting.

Thank you
Anchit Dave

No rule to make target `spandsp-reconf'. Stop. - Compatibility with Freeswitch V1.10

Hello,
I am getting the error when trying to setup the modules.

I already had FS installed and just added the steps in the extra.yml file to add the various modules.
However, I am using Fresswitch version1.10 and I notice you use v1.8
Could this error be as a result?
Side note- I have already tried this and still didn't work:
"make spandsp-reconf && make && make install"

config.status: error: cannot find input file: Makefile.in' make: *** No rule to make target spandsp-reconf'. Stop.

[Docker] Issues with custom modules on a foreign machine

TL;DR: When I build docker-drachtio-freeswitch-mrf on top of drachtio/freeswitch-grpc:latest, I can't load GRPC-dependent modules.

What I've done:

# Clone upstream image's repo
git clone https://github.com/davehorton/docker-drachtio-freeswitch-mrf
cd docker-drachtio-freeswitch-mrf

# Change base to this repository's Dockerhub-hosted image
sed -s '/^FROM drachtio/drachtio-freeswitch-base:latest$/FROM drachtio/freeswitch-grpc:latest'

# (build it...)
docker build . -t my-freeswitch-mrf

# Run the newly built image
docker run -it --rm --net=host -v "../gcs_service_account_key.json":"/tmp/gcs_service_account_key.json" my-freeswitch-mrf freeswitch

When I try loading mod_audio_fork:

freeswitch@my-pc> load mod_audio_fork
2019-04-14 11:30:40.868283 [ERR] switch_xml.c:1310 Error including /usr/local/freeswitch/conf/autoload_configs/../mrcp_profiles/*.xml
2019-04-14 11:30:40.908289 [INFO] switch_time.c:1423 Timezone reloaded 1750 definitions

+OK Reloading XML
-ERR [module load file routine returned an error]

2019-04-14 11:30:40.968272 [CRIT] switch_loadable_module.c:1522 Error Loading module /usr/local/freeswitch/mod/mod_audio_fork.so
**/usr/local/freeswitch/mod/mod_audio_fork.so: cannot open shared object file: No such file or directory**

When I try loading mod_google_tts:

freeswitch@my-pc> load mod_google_tts
2019-04-14 11:42:26.648283 [ERR] switch_xml.c:1310 Error including /usr/local/freeswitch/conf/autoload_configs/../mrcp_profiles/*.xml
2019-04-14 11:42:26.688410 [INFO] switch_time.c:1423 Timezone reloaded 1750 definitions

+OK Reloading XML
-ERR [module load file routine returned an error]

2019-04-14 11:42:26.748412 [CRIT] switch_loadable_module.c:1522 Error Loading module /usr/local/freeswitch/mod/mod_google_tts.so
**/usr/local/freeswitch/mod/mod_google_tts.so: undefined symbol: _ZTVN6google5cloud12texttospeech2v112TextToSpeech4StubE**

I expect these to load successfully, or even be loaded automatically.

PS.: It's interesting that mod_audio_fork simply doesn't exists but mod_google_tts is just wrongly-linked.

increasing the number of libwebsocket service threads of mod_audio_fork module

Hello Dave,
When i run sipp for performance test(for example, peak call to 50 and call rate to 3 cps), it seems the remote audio stream is delayed and even not received at all.
I changed MOD_AUDIO_FORK_SERVICE_THREADS to 5 but had no luck and even i followed up this link and changed freeswitch configuration but had no luck either.

https://stackoverflow.com/questions/53609817/freeswitch-blocked

Is there a reason for limiting the max thread number to 5?
Could you provide the way to increase the number over 5?

Any suggestions are appreciated.

Compiling with apt-get packages

Hi Dave,

Thank you so much for your assistance so far. I just had 1 quick question. Is it possible to compile these modules with the apt-get FreeSWITCH packages instead of building the FreeSWITCH from the source?
We tried to configure by specifying the directories but after make we came accross this issue while loading the module:

2020-08-24 12:26:32.595234 [CRIT] switch_loadable_module.c:1785 Error Loading module /usr/lib/freeswitch/mod/mod_google_tts.so **/usr/lib/freeswitch/mod/mod_google_tts.so: undefined symbol: _ZTVN6google5cloud12texttospeech2v112TextToSpeech4StubE**

Thank you
Anchit Dave

Compilation of modules with FreeSwitch v1.10.3 ends in Segmentation fault

Hi,
I tried to compile transcribe modules with FreeSWITCH v1.10.3. Compilation and installation was successful but when I try to start FreeSWITCH, It ends in segmentation fault.
Screenshot 2020-09-30 154940
I have debugged the issue for some level there are some errors with grpc library. I am attaching the freeswitch binary, coredump and bactrace logs. Please check it out, It will be a great help if this issue is resolved.

race while reading from channel variables

Hello,

We are using mod_google_transcribe for ASR. We observed race in setting the required channel variables for GSR & invoking the uuid_google_transcribe command. Worth mentioning, we are using a go client to send commands using mod_event_socket. What we ended up doing was modify the existing API & pass all the variables in the command. Setting sample rate is also dynamic which fixes #48.

If this is something which you would want, we can create a PR with modified API or a new API (say uuid_google_transcribe2), so as to not break existing applications. Please let us know. Thanks.

FYI @Chetan177

Available regions for mod_dialogflow

Hello,

https://cloud.google.com/dialogflow/es/docs/how/region#detect-intent-region-java

Flows in Dialogflow are by default in the "global" region. However, is there any support for flows that are deployed in a different region? I tried contacting a flow deployed in "Europe | Belgium | europe-west1" for example and it failed

I realized that the region was hardcoded as the global one in here
The global URL is "dialogflow.googleapis.com"
The other URLs for specific regions have a prefix such as "europe-west1-dialogflow.googleapis.com"

Our infrastructure consists of FreeSWITCH + Drachtio Server + a Drachtio App

Error logs:
FreeSWITCH:
google_glue.cpp:316 StreamingDetectIntentRequest finished with err com.google.apps.framework.request.NotFoundException: No DesignTimeAgent found for project '<PROJECTID>'. (5):

Drachtio App:
5 NOT_FOUND: com.google.apps.framework.request.NotFoundException: No DesignTimeAgent found for project '<PROJECTID>'.","code":5,"details":"com.google.apps.framework.request.NotFoundException: No DesignTimeAgent found for project '<PROJECTID>'

run dialogflow_start uuid project en-US welcome still can't use

2020-05-15 07:56:14.637560 [DEBUG] mod_dialogflow.c:146 command 8cb25d28-9681-11ea-a85d-ffcc635c2d98 test-edccbc en-US welcome
2020-05-15 07:56:14.637560 [INFO] mod_dialogflow.c:96 starting dialogflow with project test-edccbc, language en-US, event welcome, text (null).
2020-05-15 07:56:14.637560 [DEBUG] google_glue.cpp:89 GStreamer::startStream set event welcome, text (null) 0x7ff6ec0c6d90
2020-05-15 07:56:14.737545 [DEBUG] google_glue.cpp:179 grpc_read_thread: starting cb 0x7ff6ec06ab58
2020-05-15 07:56:14.737545 [INFO] mod_dialogflow.c:52 Got SWITCH_ABC_TYPE_INIT.
2020-05-15 07:56:14.737545 [DEBUG] switch_core_media_bug.c:970 Attaching BUG to sofia/internal/[email protected]
2020-05-15 07:56:14.737545 [DEBUG] switch_cpp.cpp:1187 sofia/internal/[email protected] destroy/unlink session from object
2020-05-15 07:56:14.737545 [NOTICE] switch_core_state_machine.c:386 sofia/internal/[email protected] has executed the last dialplan instruction, hanging up.
2020-05-15 07:56:14.737545 [NOTICE] switch_core_state_machine.c:388 Hangup sofia/internal/[email protected] [CS_EXECUTE] [NORMAL_CLEARING]

official googleapi repo source

Hi Dave ,
As I am new to all this..... can you give me the details of from where I can find out the googleapi package which u are using in ur ansible
Means where I can find it out in google's official repo the googleapi package
also I am using ur old commits ....as my scenario is like I want to use v1 stable version of libraries

Overlap in recordings while using mod_tts and mod_transcribe

From this packer( https://github.com/davehorton/packer-drachtio-freeswitch-dialogflow) I am using mod_transcribe and mod_tts, to repeat what the user has said as given in the example https://github.com/davehorton/drachtio-freeswitch-modules/blob/master/examples/google_transcribe.js but I find the voice of callee and caller overlapping, Please listen to the recording, there are two voices coming but they are overlapping

https://gofile.io/?c=HaPiet

I followed https://github.com/davehorton/drachtio-siprec-recording-server and modified the dialplan in
mrf_dialplan.xml to

<extension name="socket">
      <condition field="${sip_user_agent}" expression="^drachtio-fsmrf:(.*)$">
             <action application="answer"/>
             <action application="export" data="_nolocal_jitterbuffer_msec=100"/>
             <action application="set" data="RECORD_STEREO=false"/>
             <action application="mkdir" data="/home/admin/final/${strftime(%Y%m%d)"/>
             <action application="record_session" data="/home/admin/test.gsm"/>
             <action application="set" data="hangup_after_bridge=true"/>
             <action application="socket" data="${sip_h_X-esl-outbound} async full"/>
      </condition>
</extension>

But when I use the mod_dialogflow then the recording comes to be perfect, Please let me know what could be the reason for the issue or if any more information is required.

And thanks for such an awesome project

crash switch_thread_cond_wait(cb->cond, cb->mutex);

model audio_form .
function fork_session_init

switch_thread_cond_wait(cb->cond, cb->mutex);

lua code:
session:answer();
api = freeswitch.API();
local call_uuid = session:getVariable("uuid");
freeswitch.consoleLog("console", "-----------------call_uuid="..call_uuid.."\n")
api:executeString("uuid_audio_fork "..call_uuid.." start ws://192.168.0.205:9988 stereo 8k 234");

is_final flag never true when languages other than en-US is used

I am following the example in the repository for using google transcribe, this is the line of code which I am using to call the API, when the language code is en-US, it works absolutely fine but when I change it to for example en-GB as in example below I am not able to get the is_final flag as true,

ep.api('uuid_google_transcribe', [ep.uuid, 'start', 'en-GB','interim']

Here are some logs from the application in case it is needed,

1|app | received transcription: {"stability":0.01,"is_final":false,"alternatives":[{"confidence":0,"transcript":"hello"}]} 1|app | received transcription: {"stability":0.9,"is_final":false,"alternatives":[{"confidence":0,"transcript":"hello"}]} 1|app | received transcription: {"stability":0.9,"is_final":false,"alternatives":[{"confidence":0,"transcript":"hello"}]} 1|app | received transcription: {"stability":0.01,"is_final":false,"alternatives":[{"confidence":0,"transcript":" where"}]} 1|app | received transcription: {"stability":0.9,"is_final":false,"alternatives":[{"confidence":0,"transcript":"Hello"}]} 1|app | received transcription: {"stability":0.01,"is_final":false,"alternatives":[{"confidence":0,"transcript":" where's"}]} 1|app | received transcription: {"stability":0.9,"is_final":false,"alternatives":[{"confidence":0,"transcript":"hello"}]} 1|app | received transcription: {"stability":0.01,"is_final":false,"alternatives":[{"confidence":0,"transcript":" where did"}]} 1|app | received transcription: {"stability":0.9,"is_final":false,"alternatives":[{"confidence":0,"transcript":"hello"}]} 1|app | received transcription: {"stability":0.01,"is_final":false,"alternatives":[{"confidence":0,"transcript":" where did not"}]} 1|app | received transcription: {"stability":0.9,"is_final":false,"alternatives":[{"confidence":0,"transcript":"hello"}]} 1|app | received transcription: {"stability":0.01,"is_final":false,"alternatives":[{"confidence":0,"transcript":" where did man"}]} 1|app | received transcription: {"stability":0.9,"is_final":false,"alternatives":[{"confidence":0,"transcript":"hello"}]} 1|app | received transcription: {"stability":0.01,"is_final":false,"alternatives":[{"confidence":0,"transcript":" where did not give"}]} 1|app | received transcription: {"stability":0.9,"is_final":false,"alternatives":[{"confidence":0,"transcript":"hello where did"}]} 1|app | received transcription: {"stability":0.01,"is_final":false,"alternatives":[{"confidence":0,"transcript":" not giving"}]} 1|app | received transcription: {"stability":0.9,"is_final":false,"alternatives":[{"confidence":0,"transcript":"hello where did"}]} 1|app | received transcription: {"stability":0.01,"is_final":false,"alternatives":[{"confidence":0,"transcript":" not give in"}]} 1|app | received transcription: {"stability":0.9,"is_final":false,"alternatives":[{"confidence":0,"transcript":"hello where did"}]} 1|app | received transcription: {"stability":0.01,"is_final":false,"alternatives":[{"confidence":0,"transcript":" not giving me"}]} 1|app | received transcription: {"stability":0.9,"is_final":false,"alternatives":[{"confidence":0,"transcript":"hello where did"}]} 1|app | received transcription: {"stability":0.01,"is_final":false,"alternatives":[{"confidence":0,"transcript":" not giving me to"}]} 1|app | received transcription: {"stability":0.9,"is_final":false,"alternatives":[{"confidence":0,"transcript":"hello where did not"}]} 1|app | received transcription: {"stability":0.01,"is_final":false,"alternatives":[{"confidence":0,"transcript":" giving me to"}]} 1|app | received transcription: {"stability":0.9,"is_final":false,"alternatives":[{"confidence":0,"transcript":"hello where did not"}]} 1|app | received transcription: {"stability":0.01,"is_final":false,"alternatives":[{"confidence":0,"transcript":" giving me trouble"}]} 1|app | received transcription: {"stability":0.9,"is_final":false,"alternatives":[{"confidence":0,"transcript":"hello where did not giving me"}]} 1|app | received transcription: {"stability":0.01,"is_final":false,"alternatives":[{"confidence":0,"transcript":" trouble"}]} 1|app | received transcription: {"stability":0.9,"is_final":false,"alternatives":[{"confidence":0,"transcript":"hello where did not giving me trouble"}]} 1|app | received transcription: {"stability":0.9,"is_final":false,"alternatives":[{"confidence":0,"transcript":"hello where did not giving me"}]} 1|app | received transcription: {"stability":0.01,"is_final":false,"alternatives":[{"confidence":0,"transcript":" to Greenland"}]} 1|app | received transcription: {"stability":0.9,"is_final":false,"alternatives":[{"confidence":0,"transcript":"hello where did not giving me to Greenland"}]}

I tried using other languages such as en-IN but the problem is still exists, is_final flag never comes to be true but It works fine for en-US. Please let me know if any other information is required.

Thanks

freeswitch crash on dialogflow_stop

Hi Dave,

We have an issue of FreeSWITCH crash with 'dialogflow'. It crashes upon receiving 'dialogflow_stop' for a channel. It's reproducible and happens every time. I have attached fscli logs for your reference. I haven't got the call back trace yet. But can provide if needed.
The code we are using is almost 5 months old. I see there have been several checkins especially related to crash and deadlock (another issue: I see that on the fscli output, when I teardown the channel before issuing the 'dialogflow_stop' for the channel.
Can you please have a look at the logs and suggest if the issue is already fixed in the latest code.

Thanks
Ajay
trill_freeswitch_crash_fscli_test1.log

Some mod_dialogflow sessions are not freed

Dear Dave, first of all thanks for your awesome software, but could you please help me shed some light on the following issue:
My test setup:
drachtio-dialogflow-phone-gateway@master,
drachtio-server@master and
[email protected]
all running in dockers on debian 10

Under some load (1-2 CPS, 100+ calls per hour) I see leaked calls in fsmrf (using fs_cli -x "show calls").
They cannot be killed btw (says no channel for this uuid).

The difference between good and bad calls are lines after "google_dialogflow_session_cleanup: sending writesDone..".

In good case I see:
42e138f2-9583-11eb-aab6-d94b44fe44fd 2021-04-04 20:21:55.620216 [INFO] google_glue.cpp:428 google_dialogflow_session_cleanup: waiting for read thread to complete
42e138f2-9583-11eb-aab6-d94b44fe44fd 2021-04-04 20:21:55.620216 [INFO] google_glue.cpp:431 google_dialogflow_session_cleanup: read thread completed
42e138f2-9583-11eb-aab6-d94b44fe44fd 2021-04-04 20:21:55.620216 [INFO] google_glue.cpp:439 google_dialogflow_session_cleanup: Closed google session
...
42e138f2-9583-11eb-aab6-d94b44fe44fd 2021-04-04 20:21:55.620216 [DEBUG] switch_core_media_bug.c:1289 Removing BUG from sofia/drachtio_mrf/nobody@drachtio:5060
42e138f2-9583-11eb-aab6-d94b44fe44fd 2021-04-04 20:21:55.620216 [DEBUG] switch_core_state_machine.c:848 (sofia/drachtio_mrf/nobody@drachtio:5060) Callstate Change ACTIVE -> HANGUP
42e138f2-9583-11eb-aab6-d94b44fe44fd 2021-04-04 20:21:55.620216 [DEBUG] switch_core_state_machine.c:850 (sofia/drachtio_mrf/nobody@drachtio:5060) State HANGUP
42e138f2-9583-11eb-aab6-d94b44fe44fd 2021-04-04 20:21:55.620216 [DEBUG] mod_sofia.c:460 Channel sofia/drachtio_mrf/nobody@drachtio:5060 hanging up, cause: NORMAL_CLEARING
42e138f2-9583-11eb-aab6-d94b44fe44fd 2021-04-04 20:21:55.620216 [DEBUG] mod_sofia.c:514 Sending BYE to sofia/drachtio_mrf/nobody@drachtio:5060

but in bad case I don't see any lines after "google_dialogflow_session_cleanup: sending writesDone.."

And could you please take a look at d0f10ff#diff-a28b7b42e8e1c7eaccc685c261700be5fe64e57ef9a67e49dea236ed9eb1653d.

Is it accidental commit to return SWITCH_STATUS_SUCCESS on hanguphook or not (because commit is related to AWS)?
Maybe I have to use v0.2.9 release instead of master?

Understanding mod_dialogflow

Hello Dave,

I successfully installed mod_dialogflow and other module in freeswitch. But did not understand Can i use this in my use case. Please help me to understand this better. My use case is i have a freeswitch server serving 15-20 calls per day. Normal ivr interactions is happening on that. I build a application using python2.7. During ivr instruction i want to redirect user to dialogflow. Where user speak and dialogflow return me a intent and again i decide my db operation by using that intent. Basically want to build a voice chatbot over my ivr. I was validating this by building a dialplan. Where i am just answering the call and want to send that audio to dialogflow. Starting dialogflow by using uuid of that inbound call.

I really tried hard to understand. I am very much new to this freeswitch development.

Thanks

Error: "GOOGLE_APPLICATION_CREDENTIALS" environment variable must be set to path of the file containing service account json key

i have set environment on system,run export GOOGLE_APPLICATION_CREDENTIALS="/tmp/gcs_service_account_key.json"
and create config file like this
cat /usr/local/freeswitch/conf/autoload_configs/google_tts.xml




but if i load the mod_google_tts, it also tell me Error: "GOOGLE_APPLICATION_CREDENTIALS" environment variable must be set to path of the file containing service account json key

and this gcs_service_account_key.json is right,so can you help me ?

audio forking problem

Hi, Dave.

Sometimes, websocket 'message' event is not received from freeswitch side even though i called uuid_audio_fork api(actually, drachtio-fsmrf forkAudioStart function).

So, i added some debugging code to eventcallback function of lws_glue.cpp and found bug pointer is null and user data is not sent to ws server even though the ws connection is successful.
I think this happens when CPU load is high or race condition.

Could you guess?
Any suggestion is appreciated.

freeswitch log is as follows:

7ef84a0c-20c4-11ec-a8b7-cd49a3992550 2021-09-29 10:28:06.491887 [DEBUG] sofia.c:7290 Channel sofia/drachtio_mrf/[email protected]:5500 entering state [ready][200]
7ef84a0c-20c4-11ec-a8b7-cd49a3992550 2021-09-29 10:28:06.491887 [DEBUG] switch_ivr_async.c:1636 No silence detection configured; assuming start of speech
7ef84a0c-20c4-11ec-a8b7-cd49a3992550 2021-09-29 10:28:06.531887 [DEBUG] switch_ivr.c:632 sofia/drachtio_mrf/[email protected]:5500 Command Execute [depth=1] answer()
7ef84a0c-20c4-11ec-a8b7-cd49a3992550 EXECUTE [depth=1] sofia/drachtio_mrf/[email protected]:5500 answer()
2021-09-29 10:28:06.571890 [DEBUG] mod_audio_fork.c:166 mod_audio_fork cmd: 7ef84a0c-20c4-11ec-a8b7-cd49a3992550 start http://192.168.10.69:3440/a97f0e7e-200f-11ec-8f5e-537098f85be9 mono 8000 '{"event":"start","data":{"startTime":"2021-09-29T01:28:05.907Z","projectId":"09a16296-9f9d-441c-b233-aed8092c0021","callingNumber":"2400","calledNumber":"3500","direction":"inbound","tid":"dDhKjM2hzeKy17SQMFZs","mediaUuid":"7ef84a0c-20c4-11ec-a8b7-cd49a3992550","wsEndpoint":"ws://localhost:3391/call/socket/09a16296-9f9d-441c-b233-aed8092c0021?callId=a97f0e7e-200f-11ec-8f5e-537098f85be9","ttl":1200,"connectionTimeout":10,"payload":{}}}'
7ef84a0c-20c4-11ec-a8b7-cd49a3992550 2021-09-29 10:28:06.571890 [INFO] mod_audio_fork.c:73 mod_audio_fork: streaming 8000 sampling to 192.168.10.69 path /a97f0e7e-200f-11ec-8f5e-537098f85be9 port 3440 tls: no.
7ef84a0c-20c4-11ec-a8b7-cd49a3992550 2021-09-29 10:28:06.571890 [DEBUG] mod_audio_fork.c:89 calling fork_session_init.
7ef84a0c-20c4-11ec-a8b7-cd49a3992550 2021-09-29 10:28:06.571890 [DEBUG] lws_glue.cpp:266 (6) no resampling needed for this call
7ef84a0c-20c4-11ec-a8b7-cd49a3992550 2021-09-29 10:28:06.571890 [DEBUG] lws_glue.cpp:269 (6) fork_data_init
2021-09-29 10:28:06.571890 [NOTICE] lws_glue.cpp:296 7ef84a0c-20c4-11ec-a8b7-cd49a3992550 after adding connect there are 1 pending connects

2021-09-29 10:28:06.571890 [NOTICE] lws_glue.cpp:296 7ef84a0c-20c4-11ec-a8b7-cd49a3992550 attempting connection, wsi is 0x7f21b4021790

7ef84a0c-20c4-11ec-a8b7-cd49a3992550 2021-09-29 10:28:06.571890 [DEBUG] mod_audio_fork.c:95 adding bug.
7ef84a0c-20c4-11ec-a8b7-cd49a3992550 2021-09-29 10:28:06.571890 [DEBUG] switch_core_media_bug.c:970 Attaching BUG to sofia/drachtio_mrf/[email protected]:5500



**_7ef84a0c-20c4-11ec-a8b7-cd49a3992550 2021-09-29 10:28:06.571890 [ERR] lws_glue.cpp:205 no bug_**



7ef84a0c-20c4-11ec-a8b7-cd49a3992550 2021-09-29 10:28:06.571890 [DEBUG] mod_audio_fork.c:99 setting bug private data.
7ef84a0c-20c4-11ec-a8b7-cd49a3992550 2021-09-29 10:28:06.571890 [DEBUG] mod_audio_fork.c:102 exiting start_capture.
7ef84a0c-20c4-11ec-a8b7-cd49a3992550 2021-09-29 10:28:06.631910 [DEBUG] switch_core_io.c:448 Setting BUG Codec PCMA:8
7ef84a0c-20c4-11ec-a8b7-cd49a3992550 2021-09-29 10:28:06.811871 [INFO] switch_rtp.c:7680 Auto Changing audio port from 12.124.21.249:20206 to 172.26.0.1:57549

mod_google_transcribe: intermittent crash while initialising google session

(gdb) bt
#0 __GI_____strtol_l_internal (nptr=0x0, endptr=0x0, base=10, group=, loc=0x7fd3d3c6df20 <_nl_global_locale>) at ../stdlib/strtol_l.c:298
#1 0x00007fd3cd1e98cd in atoi (__nptr=) at /usr/include/stdlib.h:280
#2 google_speech_session_init (session=0x7fd3a6a0f988, responseHandler=0x7fd3cd1e7b20 , samples_per_second=, channels=1,
lang=0x7fd39c01cc9b "en-US", interim=1, ppUserData=0x7fd38a362ab8) at google_glue.cpp:344
#3 0x00007fd3cd1e831c in start_capture (flags=, interim=, lang=, session=)
at mod_google_transcribe.c:119
#4 transcribe_function (cmd=0x7fd3a6a0f988 "x\v#\244\323\177", session=0x1, stream=0x7fd38a362c20) at mod_google_transcribe.c:162
#5 0x00007fd3d4e6aaae in switch_api_execute (cmd=, arg=, session=0x0, stream=0x7fd38a362c20)
at src/switch_loadable_module.c:3009
#6 0x00007fd3ccd1a045 in api_exec (thread=0x0, obj=0x7fd38a3635a0) at mod_event_socket.c:1539
#7 0x00007fd3ccd1e654 in parse_command (listener=0x7fd386ff6928, event=0x7fd38a363808, reply=0x7fd38a363830 "", reply_len=)
at mod_event_socket.c:2310
#8 0x00007fd3ccd1f8d6 in listener_run (thread=0x0, obj=0x7fd386ff6928) at mod_event_socket.c:2744
#9 0x00007fd3d530e8e0 in dummy_worker (opaque=0x7fd37c3da088) at threadproc/unix/thread.c:151
#10 0x00007fd3d42d9064 in start_thread (arg=0x7fd38a364700) at pthread_create.c:309
#11 0x00007fd3d39b062d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

[mod_dialogflow] Question about multiple GOOGLE_APPLICATION_CREDENTIALS

Hello!

I have a quick question regarding mod_dialogflow and credentials
I'm looking to have a Freeswitch instance serving multiple Dialogflow accounts (imagine two different users giving me credentials). One of the use cases is that these two clients may call concurrently. Is there another way other than setting a global ENV VAR?

I noticed this when I dove into the code:
"missing credentials: GOOGLE_APPLICATION_CREDENTIALS must be suuplied either as an env variable (path to file) or a channel variable (json string)\n"
Is it possible that, in the drachtio application, when I receive a call I check which user is calling and then call FreeSWITCH API command uuid_set_var to add the channel variable "GOOGLE_APPLICATION_CREDENTIALS" with the corresponding service account json?

forkAudioStart play_audio respone event

I've found a fork_audio_start function in endpoint.js.
Reading mod_audio_fork documentation, I've understood that if you send back a play_audio message in ws, some kind of event will rise up in javascript app.

Exactly where do I have do expect this event to be fired? Maybe in the callback of forkAudioStart(opts, callback)?

Error when starting to intercept voice channel:

Hi,
we're trying to test Drachtio with custom FS modules to integrate with Google DialogFlow.

So far we have the custom FS version installed based on the Ansible role from another repository and drachtio-server installed from the source. These modules are on the same server. Then we have the exemplary node.js app "simple-dialogflow-example" on another server and trying to make some testing calls.
The modules seem to be connected properly, the sample app connects both to FS and drachtio-server.
The environmental variable GOOGLE_APPLICATION_CREDENTIALS is set as well and the json file with Google app credentials is on the server in accessible path.

The FreeSwitch log throws this on the console when the call is connected:

2019-10-17 07:37:58.950617 [DEBUG] sofia.c:7291 Channel sofia/drachtio_mrf/[email protected]:5061 entering state [ready][200] 2019-10-17 07:37:58.970627 [DEBUG] switch_ivr.c:625 sofia/drachtio_mrf/[email protected]:5061 Command Execute answer(undefined) EXECUTE sofia/drachtio_mrf/[email protected]:5061 answer(undefined) 2019-10-17 07:37:59.010608 [DEBUG] switch_ivr.c:625 sofia/drachtio_mrf/[email protected]:5061 Command Execute set(codec_string=PCMU) EXECUTE sofia/drachtio_mrf/[email protected]:5061 set(codec_string=PCMU) 2019-10-17 07:37:59.010608 [DEBUG] mod_dptools.c:1598 SET sofia/drachtio_mrf/[email protected]:5061 [codec_string]=[PCMU] 2019-10-17 07:37:59.090643 [DEBUG] mod_dialogflow.c:153 command 0a9761f6-f0b1-11e9-b97e-d73ac769f0aa testing123-nmhtfg en-US 20 welcome 2019-10-17 07:37:59.090643 [INFO] mod_dialogflow.c:102 starting dialogflow with project testing123-nmhtfg, language en-US, timeout: 20, event welcome. 2019-10-17 07:37:59.090643 [DEBUG] google_glue.cpp:54 GStreamer::startStream set event welcome, 0x7fa014002200 2019-10-17 07:37:59.090643 [DEBUG] google_glue.cpp:135 grpc_read_thread: starting cb 0x7fa0181ac240 2019-10-17 07:37:59.090643 [INFO] mod_dialogflow.c:56 Got SWITCH_ABC_TYPE_INIT. 2019-10-17 07:37:59.090643 [DEBUG] switch_core_media_bug.c:962 Attaching BUG to sofia/drachtio_mrf/[email protected]:5061 2019-10-17 07:37:59.090643 [DEBUG] google_glue.cpp:195 dialogflow read loop is done 2019-10-17 07:37:59.090643 [DEBUG] google_glue.cpp:91 GStreamer::finish 0x7fa014002200 2019-10-17 07:37:59.090643 [CRIT] google_glue.cpp:202 StreamingDetectIntentRequest finished with err lame client channel (2): 2019-10-17 07:37:59.090643 [INFO] mod_dialogflow.c:136 Received user command command to stop dialogflow. 2019-10-17 07:37:59.090643 [DEBUG] google_glue.cpp:91 GStreamer::finish 0x7fa014002200 2019-10-17 07:37:59.090643 [DEBUG] google_glue.cpp:44 GStreamer::~GStreamer wrote 0 packets 0x7fa014002200 2019-10-17 07:37:59.090643 [INFO] mod_dialogflow.c:61 Got SWITCH_ABC_TYPE_CLOSE. 2019-10-17 07:37:59.090643 [INFO] google_glue.cpp:313 sofia/drachtio_mrf/[email protected]:5061 Bug is not attached. 2019-10-17 07:37:59.090643 [DEBUG] mod_dialogflow.c:64 Finished SWITCH_ABC_TYPE_CLOSE. 2019-10-17 07:37:59.090643 [DEBUG] switch_core_media_bug.c:1276 Removing BUG from sofia/drachtio_mrf/[email protected]:5061 2019-10-17 07:37:59.090643 [INFO] google_glue.cpp:308 google_dialogflow_session_cleanup: Closed google session 2019-10-17 07:37:59.090643 [INFO] mod_dialogflow.c:138 stopped dialogflow. 2019-10-17 07:37:59.090643 [DEBUG] google_glue.cpp:210 dialogflow read thread exiting 2019-10-17 07:37:59.330632 [DEBUG] switch_rtp.c:7550 Correct audio ip/port confirmed. 2019-10-17 07:37:59.330632 [DEBUG] switch_core_io.c:448 Setting BUG Codec PCMU:0 2019-10-17 07:38:05.170614 [DEBUG] switch_ivr.c:625 sofia/drachtio_mrf/[email protected]:5061 Command Execute hangup() EXECUTE sofia/drachtio_mrf/[email protected]:5061 hangup()

Can you point me to the right direction where should I look for the solution?
Thank you in advance.

Googleapis files not being found when making mod_google_tts

Hi,
I keep getting this error at the step of making mod_google_tts.

Is there any change to the version og googleapis used? I'm using "git clone -b dialogflow-v2-support https://github.com/davehorton/googleapis"

ERROR:

making all mod_google_tts
make[4]: Entering directory `/usr/local/src/freeswitch/src/mod/applications/mod_google_tts'
CC mod_google_tts_la-mod_google_tts.lo
CXX mod_google_tts_la-google_glue.lo
google_glue.cpp:6:60: fatal error: google/cloud/texttospeech/v1/cloud_tts.grpc.pb.h: No such file or directory
#include "google/cloud/texttospeech/v1/cloud_tts.grpc.pb.h"

[mod_google_transcribe] Unable to execute

Hi Dave,

We come across the drachtio-freeswitch-modules particularly for mod_google_transcribe. We have successfully compiled and loaded the module on our FreeSWITCH version 'FreeSWITCH Version 1.10.2-dev+git20190917T160350Z15ad4c23e2~64bit (git 15ad4c2 2019-09-17 16:03:50Z 64bit)'.

But what we are trying to attempt is to have a simple custom script, wherein we receive an incoming call and it basically executes a javascript file under the location {freeswitch_directory}/scripts/incoming_test.js.
In this script, we answer the call and start the transcription, followed by TTS speech using mod_google_tts and simple echo. But when we check the FreeSWITCH logs, we find no logs from mod_google_transcribe and it seems as if the API was not executing. Can you please help us and guide us?

PFA the Freeswitch logs as well as the javascript file which is triggered on an incoming call.

Thank you,
Anchit Dave

freeswitch.log
incoming_test.js.txt

compiling on debian buster for freeswitch v1.10

I'm trying to compile the code for google_transcribe. I git cloned all of it but I don't see the usual configure, make scripts in any of the folders. Is there instructions on how to make this code?

Update from v1 to v1p1beta1 for multilingual recognition support

Hello,
thank you for your amazing work! I am wondering if it is possible to update to newer version of google speech api - v1p1beta1.

I have modified the google_glue.cpp file of mod_google_transcribe module as following to support add_alternative_language_codes function:

#include <cstdlib>

#include <switch.h>
#include <switch_json.h>
#include <grpc++/grpc++.h>

#include "google/cloud/speech/v1p1beta1/cloud_speech.grpc.pb.h"

#include "mod_google_transcribe.h"

#define BUFFER_SECS (3)

using google::cloud::speech::v1p1beta1::RecognitionConfig;
using google::cloud::speech::v1p1beta1::Speech;
using google::cloud::speech::v1p1beta1::SpeechContext;
using google::cloud::speech::v1p1beta1::StreamingRecognizeRequest;
using google::cloud::speech::v1p1beta1::StreamingRecognizeResponse;
using google::cloud::speech::v1p1beta1::StreamingRecognizeResponse_SpeechEventType_END_OF_SINGLE_UTTERANCE;
using google::rpc::Status;

class GStreamer;

class GStreamer {
public:
	GStreamer(switch_core_session_t *session, u_int16_t channels, char* lang, int interim) : 
    m_session(session), m_writesDone(false) {
    const char* var;
    const char *hints;
    switch_channel_t *channel = switch_core_session_get_channel(session);

		if (var = switch_channel_get_variable(channel, "GOOGLE_APPLICATION_CREDENTIALS")) {
			auto channelCreds = grpc::SslCredentials(grpc::SslCredentialsOptions());
			auto callCreds = grpc::ServiceAccountJWTAccessCredentials(var);
			auto creds = grpc::CompositeChannelCredentials(channelCreds, callCreds);
			m_channel = grpc::CreateChannel("speech.googleapis.com", creds);
		}
		else {
			auto creds = grpc::GoogleDefaultCredentials();
			m_channel = grpc::CreateChannel("speech.googleapis.com", creds);
		}

  	m_stub = Speech::NewStub(m_channel);
  		
		auto* streaming_config = m_request.mutable_streaming_config();
		RecognitionConfig* config = streaming_config->mutable_config();

    streaming_config->set_interim_results(interim);
    if (switch_true(switch_channel_get_variable(channel, "GOOGLE_SPEECH_SINGLE_UTTERANCE"))) {
      switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(m_session), SWITCH_LOG_DEBUG, "single_utterance\n");
      streaming_config->set_single_utterance(true);
    }

	config->set_language_code(lang);
  	config->set_sample_rate_hertz(16000);
	config->set_encoding(RecognitionConfig::LINEAR16);

    // the rest of config comes from channel vars

    // number of channels in the audio stream (default: 1)
    if (channels > 1) {
      config->set_audio_channel_count(channels);
      switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(m_session), SWITCH_LOG_DEBUG, "audio_channel_count %d\n", channels);

      // transcribe each separately?
      if (switch_true(switch_channel_get_variable(channel, "GOOGLE_SPEECH_SEPARATE_RECOGNITION_PER_CHANNEL"))) {
        config->set_enable_separate_recognition_per_channel(true);
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(m_session), SWITCH_LOG_DEBUG, "enable_separate_recognition_per_channel on\n");
      }
    }

    // max alternatives
    if (var = switch_channel_get_variable(channel, "GOOGLE_SPEECH_MAX_ALTERNATIVES")) {
      config->set_max_alternatives(atoi(var));
      switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(m_session), SWITCH_LOG_DEBUG, "max_alternatives %d\n", atoi(var));
    }

    // profanity filter
    if (switch_true(switch_channel_get_variable(channel, "GOOGLE_SPEECH_PROFANITY_FILTER"))) {
      config->set_profanity_filter(true);
      switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(m_session), SWITCH_LOG_DEBUG, "profanity_filter\n");
    }

    // enable word offsets
    if (switch_true(switch_channel_get_variable(channel, "GOOGLE_SPEECH_ENABLE_WORD_TIME_OFFSETS"))) {
      config->set_enable_word_time_offsets(true);
      switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(m_session), SWITCH_LOG_DEBUG, "enable_word_time_offsets\n");
    }

    // enable automatic punctuation
    if (switch_true(switch_channel_get_variable(channel, "GOOGLE_SPEECH_ENABLE_AUTOMATIC_PUNCTUATION"))) {
      config->set_enable_automatic_punctuation(true);
      switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(m_session), SWITCH_LOG_DEBUG, "enable_automatic_punctuation\n");
    }

    // speech model
    if (var = switch_channel_get_variable(channel, "GOOGLE_SPEECH_MODEL")) {
      config->set_model(var);
      switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(m_session), SWITCH_LOG_DEBUG, "speech model %s\n", var);
    }

    // use enhanced model
    if (switch_true(switch_channel_get_variable(channel, "GOOGLE_SPEECH_USE_ENHANCED"))) {
      config->set_use_enhanced(true);
      switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(m_session), SWITCH_LOG_DEBUG, "use_enhanced\n");
    }

    // hints  
    if (hints = switch_channel_get_variable_dup(channel, "GOOGLE_SPEECH_HINTS", SWITCH_TRUE, -1)) {
      char *phrases[500] = { 0 };
      auto *context = config->add_speech_contexts();
      int argc = switch_separate_string((char *) hints, ',', phrases, 500);
      for (int i = 0; i < argc; i++) {
        context->add_phrases(phrases[i]);
      }
      switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(m_session), SWITCH_LOG_DEBUG, "added %d hints\n", argc);
    }

    // alternative language
    if (var = switch_channel_get_variable(channel, "GOOGLE_SPEECH_ALTERNATIVE_LANG")) {
      config->add_alternative_language_codes(var);
      switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(m_session), SWITCH_LOG_DEBUG, "alternative lang %s\n", var);
    }

  	// Begin a stream.
  	m_streamer = m_stub->StreamingRecognize(&m_context);

  	// Write the first request, containing the config only.
  	m_streamer->Write(m_request);
	}

	~GStreamer() {
		switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(m_session), SWITCH_LOG_DEBUG, "GStreamer::~GStreamer - deleting channel and stub\n");
	}

	bool write(void* data, uint32_t datalen) {
    m_request.set_audio_content(data, datalen);
    bool ok = m_streamer->Write(m_request);
    return ok;
  }

	uint32_t nextMessageSize(void) {
		uint32_t size = 0;
		m_streamer->NextMessageSize(&size);
		return size;
	}

	bool read(StreamingRecognizeResponse* response) {
		return m_streamer->Read(response);
	}

	grpc::Status finish() {
		return m_streamer->Finish();
	}

	void writesDone() {
    // grpc crashes if we call this twice on a stream
    if (!m_writesDone) {
      m_streamer->WritesDone();
      m_writesDone = true;
    }
	}

protected:

private:
	switch_core_session_t* m_session;
  grpc::ClientContext m_context;
	std::shared_ptr<grpc::Channel> m_channel;
	std::unique_ptr<Speech::Stub> 	m_stub;
	std::unique_ptr< grpc::ClientReaderWriterInterface<StreamingRecognizeRequest, StreamingRecognizeResponse> > m_streamer;
	StreamingRecognizeRequest m_request;
  bool m_writesDone;
};

static void *SWITCH_THREAD_FUNC grpc_read_thread(switch_thread_t *thread, void *obj) {
	struct cap_cb *cb = (struct cap_cb *) obj;
	GStreamer* streamer = (GStreamer *) cb->streamer;

  // Read responses.
  StreamingRecognizeResponse response;
  while (streamer->read(&response)) {  // Returns false when no more to read.
    auto speech_event_type = response.speech_event_type();
    if (response.has_error()) {
      Status status = response.error();
      switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "grpc_read_thread: error %s (%d)\n", status.message().c_str(), status.code()) ;
    }
    switch_core_session_t* session = switch_core_session_locate(cb->sessionId);
    if (!session) {
      switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "grpc_read_thread: session %s is gone!\n", cb->sessionId) ;
      return nullptr;
    }

    for (int r = 0; r < response.results_size(); ++r) {
      auto result = response.results(r);
      cJSON * jResult = cJSON_CreateObject();
      cJSON * jAlternatives = cJSON_CreateArray();
      cJSON * jStability = cJSON_CreateNumber(result.stability());
      cJSON * jIsFinal = cJSON_CreateBool(result.is_final());

      cJSON_AddItemToObject(jResult, "stability", jStability);
      cJSON_AddItemToObject(jResult, "is_final", jIsFinal);
      cJSON_AddItemToObject(jResult, "alternatives", jAlternatives);

      for (int a = 0; a < result.alternatives_size(); ++a) {
        auto alternative = result.alternatives(a);
        cJSON* jAlt = cJSON_CreateObject();
        cJSON* jConfidence = cJSON_CreateNumber(alternative.confidence());
        cJSON* jTranscript = cJSON_CreateString(alternative.transcript().c_str());
        cJSON* jLanguageCode = cJSON_CreateString(result.language_code().c_str());
        cJSON_AddItemToObject(jAlt, "confidence", jConfidence);
        cJSON_AddItemToObject(jAlt, "transcript", jTranscript);
        cJSON_AddItemToObject(jAlt, "language_code", jLanguageCode);

        if (alternative.words_size() > 0) {
          cJSON * jWords = cJSON_CreateArray();
          switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "grpc_read_thread: %d words\n", alternative.words_size()) ;
          for (int b = 0; b < alternative.words_size(); b++) {
            auto words = alternative.words(b);
            cJSON* jWord = cJSON_CreateObject();
            cJSON_AddItemToObject(jWord, "word", cJSON_CreateString(words.word().c_str()));
            if (words.has_start_time()) {
              cJSON_AddItemToObject(jWord, "start_time", cJSON_CreateNumber(words.start_time().seconds()));
            }
            if (words.has_end_time()) {
              cJSON_AddItemToObject(jWord, "end_time", cJSON_CreateNumber(words.end_time().seconds()));
            }
            cJSON_AddItemToArray(jWords, jWord);
          }
          cJSON_AddItemToObject(jAlt, "words", jWords);
        }
        cJSON_AddItemToArray(jAlternatives, jAlt);
      }

      char* json = cJSON_PrintUnformatted(jResult);
      cb->responseHandler(session, (const char *) json);
      free(json);

      cJSON_Delete(jResult);
    }

    if (speech_event_type == StreamingRecognizeResponse_SpeechEventType_END_OF_SINGLE_UTTERANCE) {
      // we only get this when we have requested it, and recognition stops after we get this
      switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "grpc_read_thread: got end_of_utterance\n") ;
      cb->responseHandler(session, "end_of_utterance");
      cb->end_of_utterance = 1;
      streamer->writesDone();
    }
    switch_core_session_rwunlock(session);
    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "grpc_read_thread: got %d responses\n", response.results_size());
  }

  {
    switch_core_session_t* session = switch_core_session_locate(cb->sessionId);
    if (session) {
      if (1 == cb->end_of_utterance) {
        cb->responseHandler(session, "end_of_transcript");
      }
      grpc::Status status = streamer->finish();
      if (11 == status.error_code()) {
        if (std::string::npos != status.error_message().find("Exceeded maximum allowed stream duration")) {
          cb->responseHandler(session, "max_duration_exceeded");
        }
        else {
          cb->responseHandler(session, "no_audio");
        }
      }
      switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "grpc_read_thread: finish() status %s (%d)\n", status.error_message().c_str(), status.error_code()) ;
      switch_core_session_rwunlock(session);
    }
  }
  return nullptr;
}

extern "C" {
    switch_status_t google_speech_init() {
      const char* gcsServiceKeyFile = std::getenv("GOOGLE_APPLICATION_CREDENTIALS");
      if (gcsServiceKeyFile) {
        try {
          auto creds = grpc::GoogleDefaultCredentials();
        } catch (const std::exception& e) {
          switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, 
            "Error initializing google api with provided credentials in %s: %s\n", gcsServiceKeyFile, e.what());
          return SWITCH_STATUS_FALSE;
        }
      }
      return SWITCH_STATUS_SUCCESS;
    }

    switch_status_t google_speech_cleanup() {
      return SWITCH_STATUS_SUCCESS;
    }
    switch_status_t google_speech_session_init(switch_core_session_t *session, responseHandler_t responseHandler, 
          uint32_t samples_per_second, uint32_t channels, char* lang, int interim, void **ppUserData) {

      switch_channel_t *channel = switch_core_session_get_channel(session);
      struct cap_cb *cb;
      int err;

      cb =(struct cap_cb *) switch_core_session_alloc(session, sizeof(*cb));
      strncpy(cb->sessionId, switch_core_session_get_uuid(session), MAX_SESSION_ID);
      cb->end_of_utterance = 0;

      switch_mutex_init(&cb->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));

      if (samples_per_second != 16000) {
          cb->resampler = speex_resampler_init(channels, samples_per_second, 16000, SWITCH_RESAMPLE_QUALITY, &err);
        if (0 != err) {
           switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s: Error initializing resampler: %s.\n",
                                 switch_channel_get_name(channel), speex_resampler_strerror(err));
          return SWITCH_STATUS_FALSE;
        }
      } else {
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s: no resampling needed for this call\n", switch_channel_get_name(channel));
      }

      GStreamer *streamer = NULL;
      try {
        streamer = new GStreamer(session, channels, lang, interim);
        cb->streamer = streamer;
      } catch (std::exception& e) {
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s: Error initializing gstreamer: %s.\n", 
          switch_channel_get_name(channel), e.what());
        return SWITCH_STATUS_FALSE;
      }

      cb->responseHandler = responseHandler;

      // create the read thread
      switch_threadattr_t *thd_attr = NULL;
      switch_memory_pool_t *pool = switch_core_session_get_pool(session);

      switch_threadattr_create(&thd_attr, pool);
      switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
      switch_thread_create(&cb->thread, thd_attr, grpc_read_thread, cb, pool);

      *ppUserData = cb;
      return SWITCH_STATUS_SUCCESS;
    }

    switch_status_t google_speech_session_cleanup(switch_core_session_t *session, int channelIsClosing) {
      switch_channel_t *channel = switch_core_session_get_channel(session);
      switch_media_bug_t *bug = (switch_media_bug_t*) switch_channel_get_private(channel, MY_BUG_NAME);

      if (bug) {
        struct cap_cb *cb = (struct cap_cb *) switch_core_media_bug_get_user_data(bug);
        switch_mutex_lock(cb->mutex);

        // close connection and get final responses
        GStreamer* streamer = (GStreamer *) cb->streamer;
        if (streamer) {
          streamer->writesDone();

          switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "google_speech_session_cleanup: waiting for read thread to complete\n");
          switch_status_t st;
          switch_thread_join(&st, cb->thread);
          switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "google_speech_session_cleanup: read thread completed\n");

          delete streamer;
          cb->streamer = NULL;
        }

        if (cb->resampler) {
          speex_resampler_destroy(cb->resampler);
        }
        switch_channel_set_private(channel, MY_BUG_NAME, NULL);
			  switch_mutex_unlock(cb->mutex);

        if (!channelIsClosing) {
          switch_core_media_bug_remove(session, &bug);
        }

			  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "google_speech_session_cleanup: Closed stream\n");

			  return SWITCH_STATUS_SUCCESS;
      }

      switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "%s Bug is not attached.\n", switch_channel_get_name(channel));
      return SWITCH_STATUS_FALSE;
    }

    switch_bool_t google_speech_frame(switch_media_bug_t *bug, void* user_data) {
    	switch_core_session_t *session = switch_core_media_bug_get_session(bug);
    	struct cap_cb *cb = (struct cap_cb *) user_data;
		  if (cb->streamer && !cb->end_of_utterance) {
        GStreamer* streamer = (GStreamer *) cb->streamer;
        uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
        switch_frame_t frame = {};
        frame.data = data;
        frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;

        if (switch_mutex_trylock(cb->mutex) == SWITCH_STATUS_SUCCESS) {
          while (switch_core_media_bug_read(bug, &frame, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS && !switch_test_flag((&frame), SFF_CNG)) {
            if (frame.datalen) {

              if (cb->resampler) {
                spx_int16_t out[SWITCH_RECOMMENDED_BUFFER_SIZE];
                spx_uint32_t out_len = SWITCH_RECOMMENDED_BUFFER_SIZE;
                spx_uint32_t in_len = frame.samples;
                size_t written;

                speex_resampler_process_interleaved_int(cb->resampler,
                  (const spx_int16_t *) frame.data,
                  (spx_uint32_t *) &in_len,
                  &out[0],
                  &out_len);

                streamer->write( &out[0], sizeof(spx_int16_t) * out_len);
              }

              else {
                streamer->write( frame.data, sizeof(spx_int16_t) * frame.samples);
              }
            }
          }
          switch_mutex_unlock(cb->mutex);
        }
      }
      return SWITCH_TRUE;
    }
}

And getting error

2021-01-26 19:30:25.670880 [CRIT] switch_loadable_module.c:1786 Error Loading module /usr/local/freeswitch/mod/mod_google_transcribe.so
**/usr/local/freeswitch/mod/mod_google_transcribe.so: undefined symbol: _ZTVN6google5cloud6speech9v1p1beta16Speech4StubE**

How to know the duration of stream listen by mod_google_transcribe

Google is billing the STT measured in increments rounded up to 15 seconds.
It could be useful to verify the time that Google is billing.
In order to do that, one option would be to return the duration of the file transcribed by google in the JSON body of the event.
Is it a feature that is planned in a feature released?

Not sending voice to Google Dialogflow?

While testing the exemplary node.js app with Dialogflow integration I've noticed the Freeswitch modules stopped working properly with DialogFlow in the recent versions.

Freeswitch 1.8 with modules built based on the rev 6e7ead3 worked fine but when building fresh system based on the Ansible role https://github.com/davehorton/ansible-role-fsmrf the system is not forking the voice to Google APIs and immediately reverting to the failure intent. This keeps repeating all the time.

Any advice where the problem might be?

I've attached the debug log from Freeswitch.
freeswitch_log.txt

undefined symbol: google_speech_cleanup**

Hi Deve,
compiled mod_google_transcribe perfectly and at the time of loading module in FS1.10.3 got following error any clues on this?

2021-01-01 01:54:05.273406 [CRIT] switch_loadable_module.c:1785 Error Loading module /usr/local/freeswitch/mod/mod_google_transcribe.so
/usr/local/freeswitch/mod/mod_google_transcribe.so: undefined symbol: google_speech_cleanup

got following error too
undefined symbol: _ZTVN6google5cloud6speech2v16Speech4StubE**

Trying to implement mod_google_transcribe as playanddetect of freeswitch

Hi Dave,
I am trying to implement playanddetectspeech with these modules. I am using a playback application for music and uuid_google_transcribe command for transcription. I want to stop the playback as soon as user speak, so is there any way to do that, can you help me with this ?

Thanks

Speak Speed of Google TTS

Hi,

Is it possible to adjust the speed of the Google TTS engine through ep.speak?

EDIT: if this is possible, is it also possible to adjust the pitch?

If a silly user, specifies a file path in the GOOGLE_APPLICATION_CREDENTIALS channel variable it causes a crash

Im the silly user, that didnt read the docs right, and I set the file path in GOOGLE_APPLICATION_CREDENTIALS.

the result of that is a crash with this stack trace
(gdb) info stack #0 0x00007ffacbb06a40 in grpc_impl::CompositeChannelCredentials(std::shared_ptr<grpc_impl::ChannelCredentials> const&, std::shared_ptr<grpc_impl::CallCredentials> const&) () at /usr/local/lib/libgrpc++.so.1 #1 0x00007ffa880290ed in grpc::CompositeChannelCredentials (call_creds=std::shared_ptr<class grpc_impl::CallCredentials> (empty) = {...}, channel_creds=warning: RTTI symbol not found for class 'std::_Sp_counted_ptr<grpc_impl::SecureChannelCredentials*, (__gnu_cxx::_Lock_policy)2>' warning: RTTI symbol not found for class 'std::_Sp_counted_ptr<grpc_impl::SecureChannelCredentials*, (__gnu_cxx::_Lock_policy)2>' std::shared_ptr<class grpc_impl::ChannelCredentials> (use count 1, weak count 0) = {...}) at /usr/local/include/grpcpp/security/credentials.h:80 #2 0x00007ffa880290ed in GStreamer::GStreamer(switch_core_session*, char const*, char*, char*, char*) (this=0x7ffaa80218b0, session=0x7ffaa4036358, lang=<optimized out>, projectId=<optimized out>, event=0x7ffa4c0368d9 "Welcome", text=0x7ffa4c0368e1 "Text") at google_glue.cpp:104 #3 0x00007ffa88023f90 in google_dialogflow_session_init(switch_core_session_t*, responseHandler_t, errorHandler_t, uint32_t, char*, char*, char*, char*, cap_cb**) (session=session@entry=0x7ffaa4036358, responseHandler=responseHandler@entry=0x7ffa880212f0 <responseHandler>, errorHandler=errorHandler@entry=0x7ffa880219d0 <errorHandler>, samples_per_second=<optimized out>, lang=lang@entry=0x7ffa4c0368d3 "en-AU", projectId=projectId@entry=0x7ffa4c0368c5 "newagent-tape", event=0x7ffa4c0368d9 "Welcome", text=0x7ffa4c0368e1 "Text", ppUserData=0x7ffa81c45d88) at google_glue.cpp:396 #4 0x00007ffa88021dbf in start_capture (flags=17, text=0x7ffa4c0368e1 "Text", event=0x7ffa4c0368d9 "Welcome", projectId=0x7ffa4c0368c5 "newagent-tape", lang=0x7ffa4c0368d3 "en-AU", session=0x7ffaa4036358) at mod_dialogflow.c:100 #5 0x00007ffa88021dbf in dialogflow_api_start_function (cmd=<optimized out>, session=<optimized out>, stream=0x7ffa81c45f00) at mod_dialogflow.c:172 #6 0x00007ffacce25fd5 in switch_api_execute (cmd=cmd@entry=0x7ffa4c036e18 "dialogflow_start", arg=arg@entry=0x7ffaa402ad38 "e03fdfb4-3a07-4191-9889-b9c01ccde552 newagent-tape en-AU Welcome Text", session=0x0, stream=stream@entry=0x7ffa81c45f00) at src/switch_loadable_module.c:3010 #7 0x00007ffaccebdca7 in API::execute(char const*, char const*) (this=0x7ffa4c009dd0, cmd=cmd@entry=0x7ffa4c036e18 "dialogflow_start", arg=0x7ffaa402ad38 "e03fdfb4-3a07-4191-9889-b9c01ccde552 newagent-tape en-AU Welcome Text") at src/switch_cpp.cpp:247 #8 0x00007ffa820088a1 in _wrap_API_execute(lua_State*) (L=0x7ffa4c006cc0) at mod_lua_wrap.cpp:3309 #9 0x00007ffa81dc2c75 in () at /lib/x86_64-linux-gnu/liblua5.2.so.0 #10 0x00007ffa81dce825 in () at /lib/x86_64-linux-gnu/liblua5.2.so.0 #11 0x00007ffa81dc2f9e in () at /lib/x86_64-linux-gnu/liblua5.2.so.0

the call to grpc::ServiceAccountJWTAccessCredentials(var); is actually fine, I'm just going to go out on a limb here and suggest that grpc::ServiceAccountJWTAccessCredentials(var); returns a nil pointer in this case which then causes the crash when nil is passed to grpc::CompositeChannelCredentials

The real solution is for people such as myself to not do silly things, however we have to protect against segfaults :)

audio fork not working with reINVITE scenario

Hi Dave,
When the remote SIP server sends reINVITE and sends SDP body within ACK message, my app starts audio fork but seems it does not receive audio stream correctly.

  1. RTP stream is received correctly. I could see with tcpdump.
  2. Audio fork websocket connection established correctly. My app could receive custom meta data after starting audio fork.
  3. DTMF digits are well recieved via drachtio-fsmrf endpoint event. So it seems freeswitch receives RTP stream correctly.
endpoint.on('dtmf', (event) => {
    console.log(event.dtmf);
});
  1. Audio fork is working perfectly with no reINVITE scenario.

My code snippets are as follows:

dialog.on('modify', (req, res) => {
    res.send(200, {
        body: dialog.local.sdp
    },
    (err, sent) => {
        if(err) {
            console.error(err);
            dialog.destroy((err, msg) => {
                endpoint.destroy();
            });
        }            
    },
    (ackreq) => {
        (async () => {
            try {
                let sdpnew = ackreq.body;
                await endpoint.modify(sdpnew);
                await endpoint.forkAudioStart({...});
            } catch(e) {
                console.error(e);
            }
        })()
    });
});

Any suggestions are appreciated.

Freeswitch logs are as follows:

INVITE sip:[email protected]:3419 SIP/2.0
Via: SIP/2.0/UDP 192.168.200.11:5060;rport;branch=z9hG4bKtXZmBeeU8yB0j
Max-Forwards: 70
From: <sip:192.168.200.11:5060>;tag=p6gevyrevHNvc
To: <sip:[email protected]:3419>
Call-ID: 873f2ab3-9a86-1239-9ca5-86d9aa41a241
CSeq: 27763624 INVITE
Contact: <sip:192.168.200.11:5060>
User-Agent: drachtio-fsmrf:0376b35b-969d-4c07-b365-faaad3c9ca63
Content-Type: application/sdp
Content-Length: 204
X-esl-outbound: 192.168.200.11:43225

v=0
o=- 1604634834 1604634834 IN IP4 10.1.32.34
s=dial
c=IN IP4 10.1.32.34
t=0 0
m=audio 11298 RTP/AVP 101 8
a=fmtp:101 0-15
a=rtpmap:101 telephone-event/8000
a=rtpmap:8 PCMA/8000
a=sendrecv
2020-11-06 03:53:53.361616 [NOTICE] switch_channel.c:1118 New Channel sofia/drachtio_mrf/[email protected]:5060 [afe0f41c-1fe3-11eb-9608-e76eddef566a]
2020-11-06 03:53:53.361616 [DEBUG] switch_core_state_machine.c:585 (sofia/drachtio_mrf/[email protected]:5060) Running State Change CS_NEW (Cur 1 Tot 2)
2020-11-06 03:53:53.361616 [DEBUG] sofia.c:10243 sofia/drachtio_mrf/[email protected]:5060 receiving invite from 192.168.200.11:5060 version: 1.10.1-release git f999022 2019-08-20 16:54:04Z 64bit
2020-11-06 03:53:53.361616 [DEBUG] sofia.c:7290 Channel sofia/drachtio_mrf/[email protected]:5060 entering state [received][100]
2020-11-06 03:53:53.361616 [DEBUG] sofia.c:7300 Remote SDP:
v=0
o=- 1604634834 1604634834 IN IP4 10.1.32.34
s=dial
c=IN IP4 10.1.32.34
t=0 0
m=audio 11298 RTP/AVP 101 8
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=rtpmap:8 PCMA/8000

2020-11-06 03:53:53.361616 [DEBUG] sofia.c:7703 (sofia/drachtio_mrf/[email protected]:5060) State Change CS_NEW -> CS_INIT
2020-11-06 03:53:53.361616 [DEBUG] switch_core_state_machine.c:604 (sofia/drachtio_mrf/[email protected]:5060) State NEW
2020-11-06 03:53:53.361616 [DEBUG] switch_core_state_machine.c:585 (sofia/drachtio_mrf/[email protected]:5060) Running State Change CS_INIT (Cur 1 Tot 2)
2020-11-06 03:53:53.361616 [DEBUG] switch_core_state_machine.c:628 (sofia/drachtio_mrf/[email protected]:5060) State INIT
2020-11-06 03:53:53.361616 [DEBUG] mod_sofia.c:93 sofia/drachtio_mrf/[email protected]:5060 SOFIA INIT
2020-11-06 03:53:53.361616 [DEBUG] switch_core_state_machine.c:40 sofia/drachtio_mrf/[email protected]:5060 Standard INIT
2020-11-06 03:53:53.361616 [DEBUG] switch_core_state_machine.c:48 (sofia/drachtio_mrf/[email protected]:5060) State Change CS_INIT -> CS_ROUTING
2020-11-06 03:53:53.361616 [DEBUG] switch_core_state_machine.c:628 (sofia/drachtio_mrf/[email protected]:5060) State INIT going to sleep
2020-11-06 03:53:53.361616 [DEBUG] switch_core_state_machine.c:585 (sofia/drachtio_mrf/[email protected]:5060) Running State Change CS_ROUTING (Cur 1 Tot 2)
2020-11-06 03:53:53.361616 [DEBUG] switch_channel.c:2332 (sofia/drachtio_mrf/[email protected]:5060) Callstate Change DOWN -> RINGING
2020-11-06 03:53:53.361616 [DEBUG] switch_core_state_machine.c:644 (sofia/drachtio_mrf/[email protected]:5060) State ROUTING
2020-11-06 03:53:53.361616 [DEBUG] mod_sofia.c:154 sofia/drachtio_mrf/[email protected]:5060 SOFIA ROUTING
2020-11-06 03:53:53.361616 [DEBUG] switch_core_state_machine.c:236 sofia/drachtio_mrf/[email protected]:5060 Standard ROUTING
2020-11-06 03:53:53.361616 [INFO] mod_dialplan_xml.c:637 Processing unknown <>->drachtio in context mrf
send 305 bytes to udp/[192.168.200.11]:5060 at 03:53:53.373010:
------------------------------------------------------------------------
SIP/2.0 100 Trying
Via: SIP/2.0/UDP 192.168.200.11:5060;rport=5060;branch=z9hG4bKtXZmBeeU8yB0j
From: <sip:192.168.200.11:5060>;tag=p6gevyrevHNvc
To: <sip:[email protected]:3419>
Call-ID: 873f2ab3-9a86-1239-9ca5-86d9aa41a241
CSeq: 27763624 INVITE
User-Agent: drachtio MRF
Content-Length: 0

Dialplan: sofia/drachtio_mrf/[email protected]:5060 parsing [mrf->socket] continue=false
Dialplan: sofia/drachtio_mrf/[email protected]:5060 Regex (PASS) [socket] ${sip_user_agent}(drachtio-fsmrf:0376b35b-969d-4c07-b365-faaad3c9ca63) =~ /^drachtio-fsmrf:(.*)$/ break=on-false
Dialplan: sofia/drachtio_mrf/[email protected]:5060 Action answer()
Dialplan: sofia/drachtio_mrf/[email protected]:5060 Action sched_hangup(+3600 max_call_timeout)
Dialplan: sofia/drachtio_mrf/[email protected]:5060 Action socket(${sip_h_X-esl-outbound} async full)
2020-11-06 03:53:53.361616 [DEBUG] switch_core_state_machine.c:287 (sofia/drachtio_mrf/[email protected]:5060) State Change CS_ROUTING -> CS_EXECUTE
2020-11-06 03:53:53.361616 [DEBUG] switch_core_state_machine.c:644 (sofia/drachtio_mrf/[email protected]:5060) State ROUTING going to sleep
2020-11-06 03:53:53.361616 [DEBUG] switch_core_state_machine.c:585 (sofia/drachtio_mrf/[email protected]:5060) Running State Change CS_EXECUTE (Cur 1 Tot 2)
2020-11-06 03:53:53.361616 [DEBUG] switch_core_state_machine.c:651 (sofia/drachtio_mrf/[email protected]:5060) State EXECUTE
2020-11-06 03:53:53.361616 [DEBUG] mod_sofia.c:209 sofia/drachtio_mrf/[email protected]:5060 SOFIA EXECUTE
2020-11-06 03:53:53.361616 [DEBUG] switch_core_state_machine.c:329 sofia/drachtio_mrf/[email protected]:5060 Standard EXECUTE
EXECUTE [depth=0] sofia/drachtio_mrf/[email protected]:5060 answer()
2020-11-06 03:53:53.361616 [DEBUG] switch_core_media.c:5506 Set telephone-event payload to 101@8000
2020-11-06 03:53:53.361616 [DEBUG] switch_core_media.c:5590 Audio Codec Compare [PCMA:8:8000:20:64000:1]/[opus:116:48000:20:0:1]
2020-11-06 03:53:53.361616 [DEBUG] switch_core_media.c:5590 Audio Codec Compare [PCMA:8:8000:20:64000:1]/[PCMU:0:8000:20:64000:1]
2020-11-06 03:53:53.361616 [DEBUG] switch_core_media.c:5590 Audio Codec Compare [PCMA:8:8000:20:64000:1]/[PCMA:8:8000:20:64000:1]
2020-11-06 03:53:53.361616 [DEBUG] switch_core_media.c:5645 Audio Codec Compare [PCMA:8:8000:20:64000:1] ++++ is saved as a match
2020-11-06 03:53:53.361616 [DEBUG] switch_core_media.c:3834 Set Codec sofia/drachtio_mrf/[email protected]:5060 PCMA/8000 20 ms 160 samples 64000 bits 1 channels
2020-11-06 03:53:53.361616 [DEBUG] switch_core_codec.c:111 sofia/drachtio_mrf/[email protected]:5060 Original read codec set to PCMA:8
2020-11-06 03:53:53.361616 [DEBUG] switch_core_media.c:5849 Set telephone-event payload to 101@8000
2020-11-06 03:53:53.361616 [DEBUG] switch_core_media.c:5907 sofia/drachtio_mrf/[email protected]:5060 Set 2833 dtmf send payload to 101 recv payload to 101
2020-11-06 03:53:53.361616 [DEBUG] switch_core_media.c:8658 AUDIO RTP [sofia/drachtio_mrf/[email protected]:5060] 192.168.200.11 port 12114 -> 10.1.32.34 port 11298 codec: 8 ms: 20
2020-11-06 03:53:53.361616 [DEBUG] switch_rtp.c:4408 Starting timer [soft] 160 bytes per 20ms
2020-11-06 03:53:53.361616 [DEBUG] switch_core_media.c:8972 sofia/drachtio_mrf/[email protected]:5060 Set 2833 dtmf send payload to 101
2020-11-06 03:53:53.361616 [DEBUG] switch_core_media.c:8979 sofia/drachtio_mrf/[email protected]:5060 Set 2833 dtmf receive payload to 101
2020-11-06 03:53:53.361616 [DEBUG] switch_core_media.c:9002 sofia/drachtio_mrf/[email protected]:5060 Set rtp dtmf delay to 40
2020-11-06 03:53:53.361616 [NOTICE] sofia_media.c:92 Pre-Answer sofia/drachtio_mrf/[email protected]:5060!
2020-11-06 03:53:53.361616 [DEBUG] switch_channel.c:3565 (sofia/drachtio_mrf/[email protected]:5060) Callstate Change RINGING -> EARLY
2020-11-06 03:53:53.361616 [DEBUG] switch_core_media.c:8640 Audio params are unchanged for sofia/drachtio_mrf/[email protected]:5060.
2020-11-06 03:53:53.361616 [DEBUG] mod_sofia.c:905 Local SDP sofia/drachtio_mrf/[email protected]:5060:
v=0
o=freeswitch 1604622719 1604622720 IN IP4 y.y.y.y
s=freeswitch
c=IN IP4 y.y.y.y
t=0 0
m=audio 12114 RTP/AVP 8 101
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
a=sendrecv

2020-11-06 03:53:53.361616 [NOTICE] mod_dptools.c:1406 Channel [sofia/drachtio_mrf/[email protected]:5060] has been answered
send 943 bytes to udp/[192.168.200.11]:5060 at 03:53:53.375591:
------------------------------------------------------------------------
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.200.11:5060;rport=5060;branch=z9hG4bKtXZmBeeU8yB0j
From: <sip:192.168.200.11:5060>;tag=p6gevyrevHNvc
To: <sip:[email protected]:3419>;tag=m6UZZytmvtDpF
Call-ID: 873f2ab3-9a86-1239-9ca5-86d9aa41a241
CSeq: 27763624 INVITE
Contact: <sip:[email protected]:3419;transport=udp>
User-Agent: drachtio MRF
Accept: application/sdp
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY
Supported: path, replaces
Allow-Events: talk, hold, conference, refer
Content-Type: application/sdp
Content-Disposition: session
Content-Length: 220
Remote-Party-ID: "drachtio" <sip:[email protected]>;party=calling;privacy=off;screen=no

v=0
o=freeswitch 1604622719 1604622720 IN IP4 y.y.y.y
s=freeswitch
c=IN IP4 y.y.y.y
t=0 0
m=audio 12114 RTP/AVP 8 101
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
2020-11-06 03:53:53.361616 [DEBUG] switch_channel.c:3865 (sofia/drachtio_mrf/[email protected]:5060) Callstate Change EARLY -> ACTIVE
2020-11-06 03:53:53.361616 [DEBUG] sofia.c:7290 Channel sofia/drachtio_mrf/[email protected]:5060 entering state [completed][200]
EXECUTE [depth=0] sofia/drachtio_mrf/[email protected]:5060 sched_hangup(+3600 max_call_timeout)
2020-11-06 03:53:53.361616 [DEBUG] switch_scheduler.c:252 Added task 4 switch_ivr_schedule_hangup (afe0f41c-1fe3-11eb-9608-e76eddef566a) to run at 1604638433
EXECUTE [depth=0] sofia/drachtio_mrf/[email protected]:5060 socket(192.168.200.11:43225 async full)
2020-11-06 03:53:53.361616 [NOTICE] mod_event_socket.c:447 Trying host: 192.168.200.11:43225
recv 347 bytes from udp/[192.168.200.11]:5060 at 03:53:53.413137:
------------------------------------------------------------------------
ACK sip:[email protected]:3419;transport=udp SIP/2.0
Via: SIP/2.0/UDP 192.168.200.11:5060;rport;branch=z9hG4bKU6rDD9yy571je
Max-Forwards: 70
From: <sip:192.168.200.11:5060>;tag=p6gevyrevHNvc
To: <sip:[email protected]:3419>;tag=m6UZZytmvtDpF
Call-ID: 873f2ab3-9a86-1239-9ca5-86d9aa41a241
CSeq: 27763624 ACK
Content-Length: 0

2020-11-06 03:53:53.401616 [DEBUG] sofia.c:7290 Channel sofia/drachtio_mrf/[email protected]:5060 entering state [ready][200]
2020-11-06 03:53:53.421617 [DEBUG] switch_ivr.c:632 sofia/drachtio_mrf/[email protected]:5060 Command Execute [depth=1] answer()
EXECUTE [depth=1] sofia/drachtio_mrf/[email protected]:5060 answer()
recv 662 bytes from udp/[192.168.200.11]:5060 at 03:53:53.517062:
------------------------------------------------------------------------
INVITE sip:[email protected]:3419;transport=udp SIP/2.0
Via: SIP/2.0/UDP 192.168.200.11:5060;rport;branch=z9hG4bKvFj6e4F22gr5S
Max-Forwards: 70
From: <sip:192.168.200.11:5060>;tag=p6gevyrevHNvc
To: <sip:[email protected]:3419>;tag=m6UZZytmvtDpF
Call-ID: 873f2ab3-9a86-1239-9ca5-86d9aa41a241
CSeq: 27763625 INVITE
Contact: <sip:192.168.200.11:5060>
Content-Type: application/sdp
Content-Length: 240

v=0
o=AudiocodesGW 1673539073 1673539047 IN IP4 10.1.132.21
s=Phone-Call
c=IN IP4 10.1.32.34
t=0 0
m=audio 10278 RTP/AVP 8 101
c=IN IP4 10.1.32.34
a=sendrecv
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
send 323 bytes to udp/[192.168.200.11]:5060 at 03:53:53.533772:
------------------------------------------------------------------------
SIP/2.0 100 Trying
Via: SIP/2.0/UDP 192.168.200.11:5060;rport=5060;branch=z9hG4bKvFj6e4F22gr5S
From: <sip:192.168.200.11:5060>;tag=p6gevyrevHNvc
To: <sip:[email protected]:3419>;tag=m6UZZytmvtDpF
Call-ID: 873f2ab3-9a86-1239-9ca5-86d9aa41a241
CSeq: 27763625 INVITE
User-Agent: drachtio MRF
Content-Length: 0

2020-11-06 03:53:53.521616 [DEBUG] sofia.c:7290 Channel sofia/drachtio_mrf/[email protected]:5060 entering state [received][100]
2020-11-06 03:53:53.521616 [DEBUG] sofia.c:7300 Remote SDP:
v=0
o=AudiocodesGW 1673539073 1673539047 IN IP4 10.1.132.21
s=Phone-Call
c=IN IP4 10.1.32.34
t=0 0
m=audio 10278 RTP/AVP 8 101
c=IN IP4 10.1.32.34
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
2020-11-06 03:53:53.521616 [DEBUG] switch_core_media.c:5590 Audio Codec Compare [PCMA:8:8000:20:64000:1]/[opus:116:48000:20:0:1]
2020-11-06 03:53:53.521616 [DEBUG] switch_core_media.c:5590 Audio Codec Compare [PCMA:8:8000:20:64000:1]/[PCMU:0:8000:20:64000:1]
2020-11-06 03:53:53.521616 [DEBUG] switch_core_media.c:5590 Audio Codec Compare [PCMA:8:8000:20:64000:1]/[PCMA:8:8000:20:64000:1]
2020-11-06 03:53:53.521616 [DEBUG] switch_core_media.c:5645 Audio Codec Compare [PCMA:8:8000:20:64000:1] ++++ is saved as a match
2020-11-06 03:53:53.521616 [DEBUG] switch_core_media.c:5506 Set telephone-event payload to 101@8000
2020-11-06 03:53:53.521616 [DEBUG] switch_core_media.c:5849 Set telephone-event payload to 101@8000
2020-11-06 03:53:53.521616 [DEBUG] switch_core_media.c:5907 sofia/drachtio_mrf/[email protected]:5060 Set 2833 dtmf send payload to 101 recv payload to 101
2020-11-06 03:53:53.521616 [DEBUG] switch_core_media.c:8646 Audio params changed for sofia/drachtio_mrf/[email protected]:5060 from 10.1.32.34:11298 to 10.1.32.34:10278
2020-11-06 03:53:53.521616 [DEBUG] switch_core_media.c:8658 AUDIO RTP [sofia/drachtio_mrf/[email protected]:5060] 192.168.200.11 port 12114 -> 10.1.32.34 port 10278 codec: 8 ms: 20
2020-11-06 03:53:53.521616 [DEBUG] switch_core_media.c:8687 AUDIO RTP CHANGING DEST TO: [10.1.32.34:10278]
2020-11-06 03:53:53.521616 [DEBUG] sofia.c:8239 Processing updated SDP
send 803 bytes to udp/[192.168.200.11]:5060 at 03:53:53.534411:
------------------------------------------------------------------------
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.200.11:5060;rport=5060;branch=z9hG4bKvFj6e4F22gr5S
From: <sip:192.168.200.11:5060>;tag=p6gevyrevHNvc
To: <sip:[email protected]:3419>;tag=m6UZZytmvtDpF
Call-ID: 873f2ab3-9a86-1239-9ca5-86d9aa41a241
CSeq: 27763625 INVITE
Contact: <sip:[email protected]:3419;transport=udp>
User-Agent: drachtio MRF
Accept: application/sdp
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY
Supported: path, replaces
Content-Type: application/sdp
Content-Disposition: session
Content-Length: 220

v=0
o=freeswitch 1604622719 1604622720 IN IP4 y.y.y.y
s=freeswitch
c=IN IP4 y.y.y.y
t=0 0
m=audio 12114 RTP/AVP 8 101
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
2020-11-06 03:53:53.541618 [DEBUG] sofia.c:7290 Channel sofia/drachtio_mrf/[email protected]:5060 entering state [completed][200]
recv 347 bytes from udp/[192.168.200.11]:5060 at 03:53:53.557823:
------------------------------------------------------------------------
ACK sip:[email protected]:3419;transport=udp SIP/2.0
Via: SIP/2.0/UDP 192.168.200.11:5060;rport;branch=z9hG4bKXrBZgZ05ZSerN
Max-Forwards: 70
From: <sip:192.168.200.11:5060>;tag=p6gevyrevHNvc
To: <sip:[email protected]:3419>;tag=m6UZZytmvtDpF
Call-ID: 873f2ab3-9a86-1239-9ca5-86d9aa41a241
CSeq: 27763625 ACK
Content-Length: 0
2020-11-06 03:53:53.561621 [DEBUG] sofia.c:7290 Channel sofia/drachtio_mrf/[email protected]:5060 entering state [ready][200]
2020-11-06 03:53:53.681616 [DEBUG] mod_audio_fork.c:166 mod_audio_fork cmd: afe0f41c-1fe3-11eb-9608-e76eddef566a start http://127.0.0.1:3414 mono 8k '{"event":"start"}'
2020-11-06 03:53:53.681616 [INFO] mod_audio_fork.c:73 mod_audio_fork: streaming 8000 sampling to 127.0.0.1 path / port 3414 tls: no.
2020-11-06 03:53:53.681616 [DEBUG] mod_audio_fork.c:89 calling fork_session_init.
2020-11-06 03:53:53.681616 [DEBUG] lws_glue.cpp:257 (2) no resampling needed for this call
2020-11-06 03:53:53.681616 [DEBUG] lws_glue.cpp:260 (2) fork_data_init
2020-11-06 03:53:53.681616 [NOTICE] lws_glue.cpp:287 afe0f41c-1fe3-11eb-9608-e76eddef566a after adding connect there are 1 pending connects
2020-11-06 03:53:53.681616 [DEBUG] mod_audio_fork.c:95 adding bug.
2020-11-06 03:53:53.681616 [DEBUG] switch_core_media_bug.c:970 Attaching BUG to sofia/drachtio_mrf/[email protected]:5060
2020-11-06 03:53:53.681616 [NOTICE] lws_glue.cpp:287 afe0f41c-1fe3-11eb-9608-e76eddef566a attempting connection, wsi is 0x7f4f88003bb0
2020-11-06 03:53:53.681616 [DEBUG] mod_audio_fork.c:99 setting bug private data.
2020-11-06 03:53:53.681616 [DEBUG] mod_audio_fork.c:102 exiting start_capture.
2020-11-06 03:53:53.681616 [INFO] lws_glue.cpp:166 connection successful
2020-11-06 03:53:53.681616 [DEBUG] lws_glue.cpp:169 sending initial metadata {"event":"start"}
2020-11-06 03:53:53.701615 [DEBUG] switch_core_io.c:448 Setting BUG Codec PCMA:8
2020-11-06 03:53:53.741617 [DEBUG] switch_ivr.c:632 sofia/drachtio_mrf/[email protected]:5060 Command Execute [depth=1] playback(silence_stream://-1)
EXECUTE [depth=1] sofia/drachtio_mrf/[email protected]:5060 playback(silence_stream://-1)
2020-11-06 03:53:53.741617 [DEBUG] switch_ivr_play_say.c:1492 Codec Activated L16@8000hz 1 channels 20ms
2020-11-06 03:53:53.841616 [INFO] switch_rtp.c:7680 Auto Changing audio port from 10.1.32.34:10278 to x.x.x.x:10278
2020-11-06 03:53:54.361620 [DEBUG] switch_ivr.c:632 sofia/drachtio_mrf/[email protected]:5060 Command Execute [depth=2] break()
EXECUTE [depth=2] sofia/drachtio_mrf/[email protected]:5060 break()
2020-11-06 03:53:54.381618 [DEBUG] switch_ivr_play_say.c:1933 done playing file silence_stream://-1
2020-11-06 03:53:54.421618 [DEBUG] switch_ivr.c:632 sofia/drachtio_mrf/[email protected]:5060 Command Execute [depth=1] playback(http://callstore:3810/api/play/909bf846-bcf7-4ae4-81ff-4dd60ae2689f/794783799/1604634834254.wav)
EXECUTE [depth=1] sofia/drachtio_mrf/[email protected]:5060 playback(http://callstore:3810/api/play/909bf846-bcf7-4ae4-81ff-4dd60ae2689f/794783799/1604634834254.wav)
2020-11-06 03:53:54.441618 [DEBUG] mod_httapi.c:2639 caching: url:http://callstore:3810/api/play/909bf846-bcf7-4ae4-81ff-4dd60ae2689f/794783799/1604634834254.wav to /usr/local/freeswitch/storage/http_file_cache/e5cfc633ba7b75e2af3c88a8a05c26a2.wav (156530 bytes)
2020-11-06 03:53:54.441618 [DEBUG] switch_ivr_play_say.c:1492 Codec Activated L16@8000hz 1 channels 20ms
2020-11-06 03:54:04.221618 [DEBUG] switch_ivr_play_say.c:1933 done playing file http://callstore:3810/api/play/909bf846-bcf7-4ae4-81ff-4dd60ae2689f/794783799/1604634834254.wav
2020-11-06 03:54:04.281616 [DEBUG] switch_ivr.c:632 sofia/drachtio_mrf/[email protected]:5060 Command Execute [depth=1] playback(silence_stream://-1)
EXECUTE [depth=1] sofia/drachtio_mrf/[email protected]:5060 playback(silence_stream://-1)
2020-11-06 03:54:04.281616 [DEBUG] switch_ivr_play_say.c:1492 Codec Activated L16@8000hz 1 channels 20ms
2020-11-06 03:54:39.601619 [DEBUG] switch_rtp.c:7963 RTP RECV DTMF 8:880
2020-11-06 03:54:39.601619 [INFO] switch_channel.c:522 RECV DTMF 8:880
2020-11-06 03:54:39.601619 [DEBUG] mod_dptools.c:2376 Digit 8

Unable to load mod_dialogflow and mod_google_trnascribe together

Hi,

I am unable to load both the modules together. FreeSWITCH crashes even if I unload one and load the other one, i.e. if one module gets loaded at the beginning, the other can't loaded even after unloading the first one. Freeswitch crashes with error "Socket interrupted, bye!".

Does it work for any one? I am curious to know if I am doing something wrong.

I see the following error in during make. But it works fine. So I am not sure if this is the cause of the issue.

*** Warning: Linking the shared library mod_dialogflow.la against the
*** static library /var/local/libgoogleapi.a is not portable!
libtool: link: g++ -shared -nostdlib /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbeginS.o .libs/mod_dialogflow_la-mod_dialogflow.o .libs/mod_dialogflow_la-google_glue.o .libs/mod_dialogflow_la-parser.o -Wl,-rpath -Wl,/home/asabat/work/freeswitch-trill/tools/rpm/freeswitch/build/BUILD/five9-nvoip-freeswitch-1/.libs -Wl,-rpath -Wl,/home/five9inf/freeswitch/lib -L/home/asabat/work/freeswitch-trill/tools/rpm/freeswitch/build/BUILD/five9-nvoip-freeswitch-1/libs/apr-util/xml/expat/lib/.libs -L/home/asabat/work/freeswitch-trill/tools/rpm/freeswitch/build/BUILD/five9-nvoip-freeswitch-1/libs/apr/.libs /var/local/libgoogleapi.a -L/usr/local/lib -lgrpc++ -lgrpc -lgrpc++_reflection /usr/local/lib/libprotobuf.a /home/asabat/work/freeswitch-trill/tools/rpm/freeswitch/build/BUILD/five9-nvoip-freeswitch-1/.libs/libfreeswitch.so -L/home/asabat/work/freeswitch-trill/tools/rpm/freeswitch/build/BUILD/five9-nvoip-freeswitch-1/libs/apr-util/xml/expat/lib /home/asabat/work/freeswitch-trill/tools/rpm/freeswitch/build/BUILD/five9-nvoip-freeswitch-1/libs/apr-util/xml/expat/lib/.libs/libexpat.a /home/asabat/work/freeswitch-trill/tools/rpm/freeswitch/build/BUILD/five9-nvoip-freeswitch-1/libs/apr/.libs/libapr-1.a -lpq -luuid -lpthread -lsqlite3 -lcurl -lpcre -lspeex -lspeexdsp -ledit -ltinfo -ldl -lcrypt -lrt -lz -lssl -lcrypto -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../.. -lstdc++ -lm -lc -lgcc_s /usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtendS.o /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o -Wl,-R/usr/local/lib -Wl,--no-as-needed -Wl,--as-needed -pthread -Wl,-soname -Wl,mod_dialogflow.so -o .libs/mod_dialogflow.so
libtool: link: ( cd ".libs" && rm -f "mod_dialogflow.la" && ln -s "../mod_dialogflow.la" "mod_dialogflow.la" )
make[4]: Leaving directory `/home/asabat/work/freeswitch-trill/tools/rpm/freeswitch/build/BUILD/five9-nvoip-freeswitch-1/src/mod/applications/mod_dialogflow'

trill_fs_both_modules_error_crash.log

unable to load mod_dialogflow

Unable to load mod_dialogflow gettting this error

2019-12-24 18:03:35.139452 [CRIT] switch_loadable_module.c:1522 Error Loading module /usr/local/freeswitch/mod/mod_dialogflow.so
/usr/local/freeswitch/mod/mod_dialogflow.so: undefined symbol: destroyChannelUserData

mod_google_transcribe Installation module

Hi ,
i was installing mod_google_transcribe module,
for loading module why we need to install entire FreeSWITCH?
we are linking all googleapi libs to FreeSWITCH core, is there any other way to integrate googleapi with FreeSWITCH , with out re-building FreeSWITCH?

Undefined symbol building FS with mod_dialogflow

Hello,

I have been working on updating my current build of FreeSWITCH with mod_dialogflow. I had a previously working one using FS v1.10.1, but considering the recent support provided by this PR I'm using this opportunity to bump it to more recent versions since we've been noticing some performance issues that may be resolved by more recent versions of FS.

To do that I've been looking to replicate your jambonz install script ( https://github.com/jambonz/jambonz-infrastructure/blob/main/packer/jambonz-feature-server/scripts/install_freeswitch.sh ) and your ansible role tasks ( https://github.com/drachtio/ansible-role-fsmrf/tree/master/tasks ). The difference is I'm building this using docker.

os-release of the base image:
NAME="Debian GNU/Linux" VERSION_ID="9" VERSION="9 (stretch)"

**Dockerfile: https://gist.github.com/ruipfmendes/59684e9ef9da7c0d4192ed6ae1de6354 **
the dir patches is the one containing configure.ac Makefile.am modules.conf.in modules.conf.vanilla.xml modules.conf.xml
the dir $CFG_DIR has my own FS configuration files: autoload_configs, dialplan, sip_profile and vars.xml

When launching FreeSWITCH I get this error:
2021-10-06 14:26:04.728860 [CRIT] switch_loadable_module.c:1785 Error Loading module /usr/local/freeswitch/mod/mod_dialogflow.so **/usr/local/freeswitch/mod/mod_dialogflow.so: undefined symbol: _ZN6google5cloud10dialogflow7v2beta139_Intent_Message_Image_default_instance_E**

Does anything strike you as odd at first glance?
I noticed that my issue is similar to this one #23 , but I've double-checked that we are using the same versions for the main libraries and tried multiple times to follow the instructions and I can't get it fixed but I've run out of ideas

mod_google_transcribe: segfault at google_speech_session_cleanup()

Hi,

I'd like to report a segfault.

bt:

#0  GStreamer::writesDone (this=0x0) at google_glue.cpp:142
#1  google_speech_session_cleanup (session=0x7f417c047938, channelIsClosing=1) at google_glue.cpp:321
#2  0x00007f414641286c in capture_callback (bug=0x7f4140150238, user_data=0x7f410cb1c958, type=SWITCH_ABC_TYPE_CLOSE) at mod_google_transcribe.c:66
#3  0x00007f41abfdd82a in switch_core_media_bug_close (bug=0x7f4146356bb8, destroy=SWITCH_FALSE) at src/switch_core_media_bug.c:1263
#4  0x00007f41abfdd69c in switch_core_media_bug_remove_all_function (session=0x7f417c047938, function=0x0) at src/switch_core_media_bug.c:1231
#5  0x00007f41ac009d79 in switch_core_session_hangup_state (session=0x7f417c047938, force=SWITCH_TRUE) at src/switch_core_state_machine.c:839
#6  0x00007f41ac00676a in switch_core_session_run (session=0x7f417c047938) at src/switch_core_state_machine.c:616
#7  0x00007f41abfff4bc in switch_core_session_thread (thread=0x7f41804469a0, obj=0x7f417c047938) at src/switch_core_session.c:1709
#8  0x00007f41abfff8ce in switch_core_session_thread_pool_worker (thread=0x7f41804469a0, obj=0x7f4180446830) at src/switch_core_session.c:1772
#9  0x00007f41ac71b1d4 in dummy_worker () from /opt/freeswitch/lib/libfreeswitch.so.1
#10 0x00007f41ab9836db in start_thread (arg=0x7f4146357700) at pthread_create.c:463
#11 0x00007f41ab6ac88f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

bt full:

#0  GStreamer::writesDone (this=0x0) at google_glue.cpp:142
No locals.
#1  google_speech_session_cleanup (session=0x7f417c047938, channelIsClosing=1) at google_glue.cpp:321
        cb = 0x7f410cb1c958
        streamer = 0x0
        st = SWITCH_STATUS_SUCCESS
        channel = 0x7f417c072d90
        bug = 0x7f4140150238
        __func__ = "google_speech_session_cleanup"
#2  0x00007f414641286c in capture_callback (bug=0x7f4140150238, user_data=0x7f410cb1c958, type=SWITCH_ABC_TYPE_CLOSE) at mod_google_transcribe.c:66
        session = 0x7f417c047938
        __func__ = "capture_callback"
#3  0x00007f41abfdd82a in switch_core_media_bug_close (bug=0x7f4146356bb8, destroy=SWITCH_FALSE) at src/switch_core_media_bug.c:1263
        bp = 0x7f4140150238
        __func__ = "switch_core_media_bug_close"
#4  0x00007f41abfdd69c in switch_core_media_bug_remove_all_function (session=0x7f417c047938, function=0x0) at src/switch_core_media_bug.c:1231
        bp = 0x7f4140150238
        last = 0x0
        next = 0x0
        status = SWITCH_STATUS_FALSE
        closed = 0x7f4140150238
        __func__ = "switch_core_media_bug_remove_all_function"
#5  0x00007f41ac009d79 in switch_core_session_hangup_state (session=0x7f417c047938, force=SWITCH_TRUE) at src/switch_core_state_machine.c:839
        cause = SWITCH_CAUSE_NORMAL_CLEARING
        cause_q850 = SWITCH_CAUSE_NORMAL_CLEARING
        proceed = 1
        global_proceed = 1
        do_extra_handlers = 1
        silly = 0
        index = 0
        state = CS_HANGUP
        midstate = CS_HANGUP
        endpoint_interface = 0x55ff5e1e0530
        driver_state_handler = 0x7f416b3932a0 <rtc_event_handlers>
        application_state_handler = 0x0
        hook_var = 0x3a4f1ac9ff3f3000 <error: Cannot access memory at address 0x3a4f1ac9ff3f3000>
        use_session = 0
        __func__ = "switch_core_session_hangup_state"
        __PRETTY_FUNCTION__ = "switch_core_session_hangup_state"
#6  0x00007f41ac00676a in switch_core_session_run (session=0x7f417c047938) at src/switch_core_state_machine.c:616
        global_proceed = 1
        index = 0
        proceed = 1
        do_extra_handlers = 1
        ptr = 0x0
        rstatus = SWITCH_STATUS_SUCCESS
        state = CS_HANGUP
        midstate = CS_HANGUP
        endstate = CS_HANGUP
        endpoint_interface = 0x55ff5e1e0530
        driver_state_handler = 0x7f416b3932a0 <rtc_event_handlers>
        application_state_handler = 0x0
        silly = 0
        new_loops = 500
        __PRETTY_FUNCTION__ = "switch_core_session_run"
        __func__ = "switch_core_session_run"
#7  0x00007f41abfff4bc in switch_core_session_thread (thread=0x7f41804469a0, obj=0x7f417c047938) at src/switch_core_session.c:1709
        session = 0x7f417c047938
        event = 0x7f4146356d50
        event_str = 0x0
        val = 0x7f4146356d50 "\260m5FA\177"
        __func__ = "switch_core_session_thread"
        __PRETTY_FUNCTION__ = "switch_core_session_thread"
#8  0x00007f41abfff8ce in switch_core_session_thread_pool_worker (thread=0x7f41804469a0, obj=0x7f4180446830) at src/switch_core_session.c:1772
        td = 0x7f417c040888
        pop = 0x7f417c040888
        check_status = SWITCH_STATUS_SUCCESS
        node = 0x7f4180446830
        pool = 0x7f4180446748
        __func__ = "switch_core_session_thread_pool_worker"
#9  0x00007f41ac71b1d4 in dummy_worker () from /opt/freeswitch/lib/libfreeswitch.so.1
No symbol table info available.
#10 0x00007f41ab9836db in start_thread (arg=0x7f4146357700) at pthread_create.c:463
        pd = 0x7f4146357700
        now = <optimized out>
        unwind_buf = {cancel_jmp_buf = {{jmp_buf = {139918327510784, 3401557513280429578, 139918327508672, 0, 139919301568928, 139919301568576, -3335391733362713078, -3335032375844266486}, mask_was_saved = 0}}, priv = {pad = {0x0, 0x0, 0x0, 0x0}, data = {prev = 0x0, cleanup = 0x0, canceltype = 0}}}
        not_first_call = <optimized out>
#11 0x00007f41ab6ac88f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
No locals.

We are using the latest version of the module.
Would you please take a look?

Freeswitch is crashing when using mod_google_transcribe.

Hi Dave,
I am using mod_google_transcribe with freeswitch(v1.10.5). Freeswitch is crashing when I execute hangup application on a call.
Call Flow:

  • playback application and uuid_google_transcribe (simultaneosly)
  • hangup application after 20 secs,

I went through the core dump and it is showing str = 0x7fe9bd292098 "double free or corruption (out)"

bt full for core dump is as follows:

#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007fe9bd16042a in __GI_abort () at abort.c:89
#2  0x00007fe9bd19cc00 in __libc_message (do_abort=do_abort@entry=2, fmt=fmt@entry=0x7fe9bd291fd0 "*** Error in `%s': %s: 0x%s ***\n")
    at ../sysdeps/posix/libc_fatal.c:175
#3  0x00007fe9bd1a2fc6 in malloc_printerr (action=3, str=0x7fe9bd292098 "double free or corruption (out)", ptr=<optimized out>,
    ar_ptr=<optimized out>) at malloc.c:5049
#4  0x00007fe9bd1a380e in _int_free (av=0x7fe9bd4c5b00 <main_arena>, p=0x7fe9ac0011b0, have_lock=0) at malloc.c:3905
#5  0x00007fe9bc0bd21d in speex_resampler_destroy () from /usr/lib/x86_64-linux-gnu/libspeexdsp.so.1
#6  0x00007fe968345271 in ?? () from /usr/local/freeswitch/mod/mod_google_transcribe.so
#7  0x00007fe9bf18cb76 in default_coef_probs_4x4 () from /usr/local/freeswitch/lib/libfreeswitch.so.1
#8  0x0000000000000000 in ?? ()
(gdb) bt full
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
        set = {__val = {0, 2314885530818453536, 2314885530818453536, 6732726843261788192, 7378697629483820554, 3472328296331896422,
            7378697629483806000, 3472609797883717222, 2337500343188860976, 3472328296227680304, 3467824696768081952,
            2314885530818453536, 2314885530818453536, 7166204968890474528, 3472332531824356449, 3467895053655089200}}
        pid = <optimized out>
        tid = <optimized out>
#1  0x00007fe9bd16042a in __GI_abort () at abort.c:89
        save_stage = 2
        act = {__sigaction_handler = {sa_handler = 0xa20302030303a30, sa_sigaction = 0xa20302030303a30}, sa_mask = {__val = {
              3558237752655177271, 7306588112676728931, 3472386575481332281, 3467895053655089200, 2319406791620833328,
              2319389199435444272, 7090462661995280138, 7365405400577893681, 3486968509209131365, 2337418197644357680,
              3472328296227680304, 3467824696768081952, 7377522247255656992, 3975887029563438178, 3977912562749105510,
              140641734039760}}, sa_flags = 83, sa_restorer = 0x7fe9b49918d0}
        sigs = {__val = {32, 0 <repeats 15 times>}}
#2  0x00007fe9bd19cc00 in __libc_message (do_abort=do_abort@entry=2, fmt=fmt@entry=0x7fe9bd291fd0 "*** Error in `%s': %s: 0x%s ***\n")
    at ../sysdeps/posix/libc_fatal.c:175
        ap = {{gp_offset = 40, fp_offset = 1000, overflow_arg_area = 0x7fe9b49918e0, reg_save_area = 0x7fe9b4991870}}
        fd = 2
        on_2 = <optimized out>
        list = <optimized out>
        nlist = <optimized out>
        cp = <optimized out>
        written = <optimized out>
#3  0x00007fe9bd1a2fc6 in malloc_printerr (action=3, str=0x7fe9bd292098 "double free or corruption (out)", ptr=<optimized out>,
    ar_ptr=<optimized out>) at malloc.c:5049
        buf = "00007fe9ac0011c0"
        cp = <optimized out>
        ar_ptr = <optimized out>
        ptr = <optimized out>
        str = 0x7fe9bd292098 "double free or corruption (out)"
        action = 3
#4  0x00007fe9bd1a380e in _int_free (av=0x7fe9bd4c5b00 <main_arena>, p=0x7fe9ac0011b0, have_lock=0) at malloc.c:3905
        size = <optimized out>
        fb = <optimized out>
        nextchunk = <optimized out>
        nextsize = <optimized out>
        nextinuse = <optimized out>
        prevsize = <optimized out>
---Type <return> to continue, or q <return> to quit---
        bck = <optimized out>
        fwd = <optimized out>
        errstr = <optimized out>
        locked = <optimized out>
        __func__ = "_int_free"
#5  0x00007fe9bc0bd21d in speex_resampler_destroy () from /usr/lib/x86_64-linux-gnu/libspeexdsp.so.1
No symbol table info available.
#6  0x00007fe968345271 in ?? () from /usr/local/freeswitch/mod/mod_google_transcribe.so
No symbol table info available.
#7  0x00007fe9bf18cb76 in default_coef_probs_4x4 () from /usr/local/freeswitch/lib/libfreeswitch.so.1
No symbol table info available.
#8  0x0000000000000000 in ?? ()
No symbol table info available.

I have compiled freeswitch using this configure command ./configure --with-lws=yes --with-extra=yes CPPFLAGS='-g -O0' CXXFLAGS='-g -O0'

info locals of gdb:

(gdb) info locals
size = <optimized out>
fb = <optimized out>
nextchunk = <optimized out>
nextsize = <optimized out>
nextinuse = <optimized out>
prevsize = <optimized out>
bck = <optimized out>
fwd = <optimized out>
errstr = <optimized out>
locked = <optimized out>
__func__ = "_int_free"

Can you help me with this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.