iOS - VialerSIP - отправка DTMF через Inband - PullRequest
0 голосов
/ 22 января 2019

Я использую VialerSIP для приложения iOS VOIP.

Я пытаюсь отправить DTMF через inband вместо метода:

- (BOOL)sendDTMF:(NSString * _Nonnull)character error:(NSError * _Nullable * _Nullable)error;

в классе VSLCall.

Потому что, похоже, некоторые страны (включая мою) не поддерживают:

PJMEDIA_RTP_PT_TELEPHONE_EVENTS 101

Итак, я решил отправить DTMF через inband с этим решением: https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=2ahUKEwibuKSeg4HgAhUM6LwKHT33DOAQygQwAHoECAQQCA&url=https%3A%2F%2Ftrac.pjsip.org%2Frepos%2Fwiki%2FFAQ%23inband-dtmf&usg=AOvVaw3fYXthR0Z6btU2yOWovNIF

вот так (по-быстрому):

private func generateTone(_ callId: pjsua_call_id) -> UnsafeMutableRawPointer {
        var ci = pjsua_call_info()

        let pool = pjsua_pool_create("MyCall", 512, 512)!
        let cd = pj_pool_zalloc(pool, MemoryLayout<MyCallData>.size)!
        cd.storeBytes(of: pool.pointee, as: pj_pool_t.self)

        let aPool = cd.assumingMemoryBound(to: pj_pool_t.self)
        var aTonegen: UnsafeMutablePointer<pjmedia_port>? = cd.assumingMemoryBound(to: pjmedia_port.self)
        let aToneslot = cd.assumingMemoryBound(to: pjsua_conf_port_id.self)

        pjmedia_tonegen_create(aPool, 8000, 1, 160, 16, 0, &aTonegen)
        pjsua_conf_add_port(aPool, aTonegen!, aToneslot)

        pjsua_call_get_info(callId, &ci)
        pjsua_conf_connect(aToneslot.pointee, ci.conf_slot)

        pjsua_call_set_user_data(callId, cd)

        return cd
    }

    private func play(callId: pjsua_call_id, digits: String) {
        let cString = digits.cString(using: String.defaultCStringEncoding)!
        let newString: String = NSString(bytes: cString, length: Int(digits.count), encoding:String.Encoding.ascii.rawValue)! as String
        let key2Pointer = UnsafePointer<Int8>(newString)

        let cd = pjsua_call_get_user_data(callId) ?? generateTone(callId)

        let tonegen = cd.assumingMemoryBound(to: pjmedia_port.self)

        var tone = pjmedia_tone_digit(digit: key2Pointer.pointee, on_msec: 100, off_msec: 200, volume: 0)
        pjmedia_tonegen_play_digits(tonegen, 1, &tone, 0)
    }

    private func deinitTone(callId: pjsua_call_id) {
        guard let cd = pjsua_call_get_user_data(callId) else { return }

        let aPool = cd.assumingMemoryBound(to: pj_pool_t.self)
        let aTonegen = cd.assumingMemoryBound(to: pjmedia_port.self)
        let aToneslot = cd.assumingMemoryBound(to: pjsua_conf_port_id.self)

        pjsua_conf_remove_port(aToneslot.pointee)
        pjmedia_port_destroy(aTonegen)
        pj_pool_release(aPool)

        pjsua_call_set_user_data(callId, nil)
    }

Затем я попытался отправить DTMF, используя:

self.play(callId: pjsua_call_id(self.activeCall.callId), digits: numberString)

Но когда я вызываю эту функцию, процессор переполняется. Я не знаю почему: (.

Пожалуйста, дайте мне любой совет, это будет огромной помощью для решения моей проблемы.

Спасибо.

...