// mini 版本 myrobot,可进行学习
// 通过media bug 来对channel进行监听,实时获取音频流 20ms, 160 samples

#include <switch.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdarg.h>
#include <termios.h>
#include <sys/resource.h>
#include <openssl/md5.h>
#include <iconv.h>  
#include <semaphore.h>
#include <netinet/in.h>
#include <sys/poll.h>
#include <sys/wait.h>
#include <sys/epoll.h>
#include <arpa/inet.h>

/*! Syntax of the API call. */
#define ROBOT_SYNTAX "<uuid> <stop|wavefilename.wav|http://xxxx>"

/*! Number of expected parameters in api call. */
#define ROBOT_PARAMS 2

#define ROBOT_EVENT_ASR "myrobot::asr"

static switch_bool_t robot_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type);

#define MAX_VOICE_LEN 240000          
#define MAX_VOICE_LEN_BASE64 645000  
int use_asr = 8,use_tts=2,use_cache=0,use_url=0;
#define MAXFILES 8
#define TTS_MAX_SIZE 900 
#define MAX_HZ_SIZE  240  
typedef struct robot_session_info {    
    int index;
    int filetime;
    int fileplaytime;
    int nostoptime;
    int asrtimeout;
    int asr;
    int play, pos;
    int sos, eos, ec, count;
    int eos_silence_threshold;    
    int final_timeout_ms;
    int silence_threshold;
    int harmonic;
    int monitor;
    int lanid;
    switch_core_session_t *session;         
    char taskid[32];
    char groupid[32];
    char telno[32];
    char userid[64];
    char callid[64];
    char orgi[64];
    char extid[64];
    char uuid[64];
    char uuidbak[64];
    char recordfilename[128];    
    char para1[256];
    char para2[256];
    char para3[256];//yhy2019-03-19 custom
    char filename[TTS_MAX_SIZE];
    short buffer[MAX_VOICE_LEN];//yhy2018-08-04 Ö§³Ö8sÔ¤´æ    64000²ÉÑùµã    
} robot_session_info_t;

int GetPrivateProfileString(const char*set,const char*cmd,const char*def,char*res,int para_len,const char*filename)
{
    FILE     *fp=NULL;
    char    tmp[500];
    char     line_str[500];
    int     i,len;

strcpy(res,def);
    fp=fopen(filename,"r");
    if(fp==NULL){printf("open %s fail",filename);    return 0;}
    while (fgets(line_str, 256, fp))
    {
        len=strlen(line_str);
        for(i=0;i<len;i++)
        {
            if(line_str[i]=='\r'){line_str[i]=0; break;}
            if(line_str[i]=='\n'){line_str[i]=0; break;}
        }
        len=strlen(line_str);
        if(line_str[0]=='#' || len<3) continue;
        strcpy(tmp,line_str);
        for(i=0; i<len;i++)
        {
            if(tmp[i]=='=') break;
        }
        tmp[i]='\0';
        if(strcmp(cmd,tmp)==0)
        {
            i++;
            strcpy(res,line_str+i);
            break;
        }
    }
    fclose(fp);
    return 0;

}

SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_vmd_shutdown);
SWITCH_MODULE_LOAD_FUNCTION(mod_vmd_load);
SWITCH_MODULE_DEFINITION(mod_vmd, mod_vmd_load, mod_vmd_shutdown, NULL);
SWITCH_STANDARD_APP(robot_start_function);

SWITCH_MODULE_LOAD_FUNCTION(mod_vmd_load)
{
    char tmp[256];
    FILE* fp;    
    char line_str[1024],*p;
    int i,len;
    switch_application_interface_t *app_interface;
    switch_api_interface_t *api_interface;

if (switch_event_reserve_subclass(ROBOT_EVENT_ASR) != SWITCH_STATUS_SUCCESS) {
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Robot Couldn't register subclass %s!\n", ROBOT_EVENT_ASR);
        return SWITCH_STATUS_TERM;
    }
    /* connect my internal structure to the blank pointer passed to me */
    *module_interface = switch_loadable_module_create_module_interface(pool, modname);

switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Robot enabled,monitor=%d,use_asr=%d,use_tts=%d\n",1,use_asr,2);

SWITCH_ADD_APP(app_interface, "myrobot", "myrobot", "ai robot", robot_start_function, "[stop|restart|start|wavefilename.wav]", SAF_NONE);

/* indicate that the module should continue to be loaded */
    return SWITCH_STATUS_SUCCESS;
}

SWITCH_STANDARD_APP(robot_start_function)
{
    switch_media_bug_t *bug;
    switch_status_t status;
    switch_channel_t *channel;
    robot_session_info_t *robot_info;

if (session == NULL)
        return;

channel = switch_core_session_get_channel(session);

/* Is this channel already set? */
    bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_robot_");
    /* If yes */
    if (bug != NULL)
    {
        /* We have already started */
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Robot Cannot run 2 at once on the same channel!\n");
        return;
    }
    robot_info = (robot_session_info_t *)malloc(sizeof(robot_session_info_t));
    if(robot_info==NULL) return;
    robot_info->session = session;
    strcpy(robot_info->uuid, switch_core_session_get_uuid(robot_info->session));

status = switch_core_media_bug_add(session, "vmd", NULL, robot_callback, robot_info, 0, SMBF_READ_REPLACE, &bug);

if (status != SWITCH_STATUS_SUCCESS) {
        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Robot Failure hooking to stream\n");
        return;
    }
    switch_channel_set_private(channel, "_robot_", bug);
}

SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_vmd_shutdown)
{
    int i;
    switch_event_free_subclass(ROBOT_EVENT_ASR);
    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "myapplication disabled\n");
    return SWITCH_STATUS_SUCCESS;
}

static switch_bool_t process_close(robot_session_info_t *rh)
{
    switch_channel_t *channel;            
    char info[2048], result[2048];
    int send=1;            
    rh->uuid[0] = 0;    
    rh->index = -1;    
    channel = switch_core_session_get_channel(rh->session);
    switch_channel_set_private(channel, "_robot_", NULL);
    free(rh);
    return SWITCH_TRUE;
}

static switch_bool_t robot_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
{
    robot_session_info_t *robot_info;
//    switch_codec_t *read_codec;
    switch_frame_t *frame;

robot_info = (robot_session_info_t *) user_data;
    if (robot_info == NULL) {
        return SWITCH_FALSE;
    }

switch (type) {

case SWITCH_ABC_TYPE_INIT:
        break;

case SWITCH_ABC_TYPE_READ_REPLACE:
        if(robot_info->uuid[0]==0) break;
        frame = switch_core_media_bug_get_read_replace_frame(bug);
        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "received data\n");
        break;
    
    case SWITCH_ABC_TYPE_CLOSE:
        process_close(robot_info);
        break;
    default:
        break;
    }

return SWITCH_TRUE;
}

freeswitch 自定义application相关推荐

  1. Android 自定义Application

    在android中 自定义Application 常用的作用是 1 保存在程序运行中的全局变量 实例: public class GlobalApp extends Application{ priv ...

  2. MOSS点滴(2):自定义Application Page

    在MOSS中后台管理的页面都是Application Page,比如网站设置的页面(settings.aspx)就是典型的Application Page,它不能被Sharepoint Desiger ...

  3. freeswitch的application及号码集

    号码集 886 代接 870重拨 88****监听话机 779监听任意的,按*号听下一个 *69/869回拨,未接电话 80** 从组里删除以**结尾的电话 81** 向组里添加**结尾的电话 82* ...

  4. Android自定义Application的作用

    1.保存在程序运行中的全局变量 public class GlobalApp extends Application{private UserData udata ; public UserData ...

  5. android 6.0 自定义application,Android6.0之App中的资源管理对象创建

    Android与资源管理相关的类Resouces和AssetManager很有必要清楚他们的创建过程. 与资源查找与加载操作相关的类 资源查找与加载主要是靠Android资源管理框架来完成的,而And ...

  6. 【Android 热修复】热修复原理 ( 合并两个 Element[] dexElements | 自定义 Application 加载 Dex 设置 | 源码资源 )

    文章目录 一.合并两个 Element[] dexElements 二. 完整修复包加载工具类 三. 源码资源 一.合并两个 Element[] dexElements 在 [Android 热修复] ...

  7. freeswitch实现监听_基于freeswitch的智能外呼2-自定义freeswitch模块

    // mini 版本 myrobot,可进行学习, 自定义freeswitch application// 通过media bug 来对channel进行监听,实时获取音频流 20ms, 160 sa ...

  8. 为SharePoint 2010创建Application Page

    如果不了解什么是Application Page,可以参考我以前写过的这篇文章.SharePoint 2010的页面模型没有太多的变化,基本和2007保持一致.对于开发人员而言,为SharePoint ...

  9. android application常见错误

    不过自定义Application也并没有什么副作用,它和单例模式二选一都可以实现同样的功能,但是我见过有一些项目,会把自定义Application和单例模式混合到一起使用,这就让人大跌眼镜了.一个非常 ...

  10. Android开发技巧--Application, ListView排列,格式化浮点数,string.xml占位符,动态引用图片...

    一. Application用途 1. Application用途 创建Application时机 : Application在启动的时候会调用Application无参的构造方法创建实例; Appl ...

最新文章

  1. 当sql 没有足够的内存执行程序利用命令执行
  2. python template用法_python中Template的使用介绍
  3. 004 - PHP git
  4. 京东:618 期间遭「黑公关」恶意抹黑;Adobe 回应“杀死Flash”;Bootstrap 5.0 Alpha 发布 |...
  5. Just a test
  6. Android Handler机制之总目录
  7. 《凤凰项目》读书笔记
  8. 手机里面android什么意思,wipe什么意思?安卓手机如何wipe
  9. 使用心得:[屏幕录制专家]与[Macromedia Captivate]的比拼
  10. python和c++实现 不改变长宽比缩放图片
  11. MySQL数据库实操教程(25)——权限管理
  12. C语言吸引人眼球的题目,公众号文章标题如何吸引用户眼球,12个写出好标题的技巧...
  13. 叮!丰巢智能柜那些贴心服务的正确打开方式
  14. IDC机房网络系列视频
  15. linux传不上去文件,linux下上传文件,文件上传不上去
  16. 背景图片随页面滚动放大缩小
  17. Vue如何将baes64格式的图片转成普通格式
  18. java中for(;;)表示啥意思
  19. java密码安全验证_java安全编码指南之:输入校验
  20. KITS+肾脏肿瘤预处理+重采样+窗体变换+强度裁剪

热门文章

  1. 泛泰 A850 TWRP Recovery En英/Cn简/Tw繁[2013.05.19]
  2. 全网最有效软考高项十大管理ITTO记忆:宫殿记忆法、主线记忆法、逻辑记忆法、跟踪记忆法、诗词记忆法
  3. android方法不混淆,Android 混淆时不混淆注解方法
  4. 目前使用SAP的公司列表
  5. torch.distributed多卡/多GPU/分布式DPP(二)—torch.distributed.all_reduce(reduce_mean)barrier控制进程执行顺序seed随机种子
  6. 计算机信息管理不会电脑,不要抱怨网速慢.只怪你不会调网速★让你的电脑一点都不卡...
  7. python使用win32*模块模拟人工操作——城通网盘下载器(一)
  8. 用excel做数据分析
  9. matlab信号加入白噪音再分离,Matlab中给信号增加白噪声
  10. 毕设-基于Qt的餐饮ERP管理系统