pjsip铃声和应答码

pjsip ringing tones and answer codes

我正在编写一个 pjsip 应用程序,呼叫/应答工作正常。现在我想实现当我打电话给某人时我听到铃声,当我接到电话时铃声响起。

我搜索过这个,但我只是偶然发现了在示例文件夹 (pjproject-2.4.5/pjsip-apps/src/pjsua/) 中引用 pjsua 应用程序的答案。所以我试图理解这个包含多个文件(总共大约 3k 行代码)和特殊结构的程序,这使得它更难理解。所以我无法弄清楚如何执行此功能,我将不胜感激正确方向的提示。

另一点是我可以在接听来电时提供的代码列表,因为我找不到描述代码含义的代码。

感谢您的宝贵时间。

SIP 响应代码分为 6 个 类

  • 1xx: Provisional — 收到请求,继续处理 要求;临时响应,也称为信息响应 响应,表示联系的服务器正在执行一些 进一步的行动,目前还没有明确的回应。服务器 如果预计需要超过 200 毫秒才能发送 1xx 响应 得到最终的回应。请注意,不会传输 1xx 响应 可靠地。它们永远不会导致客户端发送 ACK。临时 (1xx) 响应可以包含消息体,包括会话 说明。

  • 2xx: Success — 操作已成功接收、理解并执行 已接受;

  • 3xx: Redirection — 需要采取进一步的行动才能 完成请求;

  • 4xx: Client Error — 请求包含错误语法或不能 在此服务器完成;

  • 5xx: Server Error — 服务器未能完成明显有效的 请求;

  • 6xx: Global Failure — 请求无法在任何服务器上完成。

    在这里你可以找到PJSIP struct which holds these codes and SIP codes description

老问题,但在这里为可能偶然发现它的任何人张贴我的答案:

正在播放铃声

假设您的铃声是一个 wav 文件,您需要创建一个 wav 播放器并将其端口连接到您的输出设备。 wav 文件将循环播放,直到您断开端口,然后在您重新连接时重新开始。

调用 init_ringtone_player 应该在调用 pjsua_init 之后进行。 ringtone_port_info 是一个全局结构,用于跟踪端口和环状态。

typedef struct _ringtone_port_info {
    int ring_on;
    int ring_slot;
    pjmedia_port *ring_port;
    pj_pool_t *pool;
} ringtone_port_info_t;

static ringtone_port_info_t ringtone_port_info;

static void init_ringtone_player() {

    int file_slot;
    pj_pool_t *pool;
    pjmedia_port *file_port;
    pj_status_t status;

    pool = pjsua_pool_create("wav", 4000, 4000);

    status = pjmedia_wav_player_port_create(pool, "ringtone.wav", 
        0, 0, 0, &file_port);

    if (status != PJ_SUCCESS) {
        error_exit("Error creating WAV player port", status);
        return;
    }

    status = pjsua_conf_add_port(pool, file_port, &file_slot);

    if (status != PJ_SUCCESS) {
        error_exit("Error adding port to conference", status);
        return;
    }

    ringtone_port_info = (ringtone_port_info_t) { .ring_on = 0, 
        .ring_slot = file_slot, .ring_port = file_port , .pool = pool };

}

然后,根据需要创建启动和停止铃声的功能(即在 on_incoming_callon_call_state 期间或任何地方)。这里要注意的重要函数调用是 pjsua_conf_connect.

pj_status_t start_ring() {
    pj_status_t status;

    if (ringtone_port_info.ring_on) {
        printf("Ringtone port already connected\n");
        return PJ_SUCCESS;
    }

    printf("Starting ringtone\n");
    status = pjsua_conf_connect(ringtone_port_info.ring_slot, 0);
    ringtone_port_info.ring_on = 1;
    if (status != PJ_SUCCESS)
        error_exit("Error connecting ringtone port", status);
    return status;
}

pj_status_t stop_ring() {
    pj_status_t status;

    if (!ringtone_port_info.ring_on) {
        printf("Ringtone port already disconnected\n");
        return PJ_SUCCESS;
    }

    printf("Stopping ringtone\n");
    status = pjsua_conf_disconnect(ringtone_port_info.ring_slot, 0);
    ringtone_port_info.ring_on = 0;
    if (status != PJ_SUCCESS)
        error_exit("Error disconnecting ringtone port", status);
    return status;
}

确保在完成释放池(或手动释放)后调用 pjsua_destroy

SIP 响应代码

请在此处查看状态代码列表:

https://www.pjsip.org/pjsip/docs/html/group__PJSIP__MSG__LINE.htm#

您可以使用 200 接受和 603 拒绝(使用 pjsua_call_answer