void VoipPreference::unserialize(const YAML::Node &in)
{
    const auto &node = in[CONFIG_LABEL];
    parseValue(node, PLAY_DTMF_KEY, playDtmf_);
    parseValue(node, PLAY_TONES_KEY, playTones_);
    parseValue(node, PULSE_LENGTH_KEY, pulseLength_);
    parseValue(node, SYMMETRIC_RTP_KEY, symmetricRtp_);
    parseValue(node, ZID_FILE_KEY, zidFile_);
}
void HookPreference::unserialize(const YAML::Node &in)
{
    const auto &node = in[CONFIG_LABEL];

    parseValue(node, NUMBER_ADD_PREFIX_KEY, numberAddPrefix_);
    parseValue(node, SIP_ENABLED_KEY, sipEnabled_);
    parseValue(node, URL_COMMAND_KEY, urlCommand_);
    parseValue(node, URL_SIP_FIELD_KEY, urlSipField_);
}
void ShortcutPreferences::unserialize(const YAML::Node &in)
{
    const auto &node = in[CONFIG_LABEL];

    parseValue(node, HANGUP_SHORT_KEY, hangup_);
    parseValue(node, PICKUP_SHORT_KEY, pickup_);
    parseValue(node, POPUP_SHORT_KEY, popup_);
    parseValue(node, TOGGLE_HOLD_SHORT_KEY, toggleHold_);
    parseValue(node, TOGGLE_PICKUP_HANGUP_SHORT_KEY, togglePickupHangup_);
}
void Preferences::unserialize(const YAML::Node &in)
{
    const auto &node = in[CONFIG_LABEL];

    parseValue(node, ORDER_KEY, accountOrder_);
    parseValue(node, HISTORY_LIMIT_KEY, historyLimit_);
    parseValue(node, HISTORY_MAX_CALLS_KEY, historyMaxCalls_);
    parseValue(node, ZONE_TONE_CHOICE_KEY, zoneToneChoice_);
    parseValue(node, REGISTRATION_EXPIRE_KEY, registrationExpire_);
    parseValue(node, PORT_NUM_KEY, portNum_);
    parseValue(node, SEARCH_BAR_DISPLAY_KEY, searchBarDisplay_);
    parseValue(node, MD5_HASH_KEY, md5Hash_);
}
void VideoPreferences::unserialize(const YAML::Node &in)
{
    const auto &node = in[CONFIG_LABEL];
#ifdef RING_ACCEL
    // value may or may not be present
    try {
        parseValue(node, DECODING_ACCELERATED_KEY, decodingAccelerated_);
    } catch (...) { decodingAccelerated_ = false; } // experimental, so disabled by default
#endif
    getVideoDeviceMonitor().unserialize(in);
}
void AudioPreference::unserialize(const YAML::Node &in)
{
    const auto &node = in[CONFIG_LABEL];

    // alsa submap
    const auto &alsa = node[ALSAMAP_KEY];

    parseValue(alsa, CARDIN_KEY, alsaCardin_);
    parseValue(alsa, CARDOUT_KEY, alsaCardout_);
    parseValue(alsa, CARDRING_KEY, alsaCardring_);
    parseValue(alsa, PLUGIN_KEY, alsaPlugin_);
    parseValue(alsa, SMPLRATE_KEY, alsaSmplrate_);

    // common options
    parseValue(node, ALWAYS_RECORDING_KEY, alwaysRecording_);
    parseValue(node, AUDIO_API_KEY, audioApi_);
    parseValue(node, AGC_KEY, agcEnabled_);
    parseValue(node, CAPTURE_MUTED_KEY, captureMuted_);
    parseValue(node, NOISE_REDUCE_KEY, denoise_);
    parseValue(node, PLAYBACK_MUTED_KEY, playbackMuted_);

    // pulse submap
    const auto &pulse = node[PULSEMAP_KEY];
    parseValue(pulse, DEVICE_PLAYBACK_KEY, pulseDevicePlayback_);
    parseValue(pulse, DEVICE_RECORD_KEY, pulseDeviceRecord_);
    parseValue(pulse, DEVICE_RINGTONE_KEY, pulseDeviceRingtone_);

    // more common options!
    parseValue(node, RECORDPATH_KEY, recordpath_);
    parseValue(node, VOLUMEMIC_KEY, volumemic_);
    parseValue(node, VOLUMESPKR_KEY, volumespkr_);
}
void SIPAccountBase::unserialize(const YAML::Node &node)
{
    using yaml_utils::parseValue;
    using yaml_utils::parseVectorMap;

    Account::unserialize(node);

    parseValue(node, VIDEO_ENABLED_KEY, videoEnabled_);

    parseValue(node, Conf::INTERFACE_KEY, interface_);
    parseValue(node, Conf::SAME_AS_LOCAL_KEY, publishedSameasLocal_);
    std::string publishedIpAddress;
    parseValue(node, Conf::PUBLISH_ADDR_KEY, publishedIpAddress);
    IpAddr publishedIp = publishedIpAddress;
    if (publishedIp and not publishedSameasLocal_)
        setPublishedAddress(publishedIp);

    int port = sip_utils::DEFAULT_SIP_PORT;
    parseValue(node, Conf::PUBLISH_PORT_KEY, port);
    publishedPort_ = port;

    parseValue(node, Conf::DTMF_TYPE_KEY, dtmfType_);

    // get tls submap
    const auto &tlsMap = node[Conf::TLS_KEY];
    parseValue(tlsMap, Conf::CERTIFICATE_KEY, tlsCertificateFile_);
    parseValue(tlsMap, Conf::CALIST_KEY, tlsCaListFile_);
    parseValue(tlsMap, Conf::TLS_PASSWORD_KEY, tlsPassword_);
    parseValue(tlsMap, Conf::PRIVATE_KEY_KEY, tlsPrivateKeyFile_);

    unserializeRange(node, Conf::AUDIO_PORT_MIN_KEY, Conf::AUDIO_PORT_MAX_KEY, audioPortRange_);
    unserializeRange(node, Conf::VIDEO_PORT_MIN_KEY, Conf::VIDEO_PORT_MAX_KEY, videoPortRange_);

    // ICE - STUN/TURN
    if (not isIP2IP()) {
        parseValue(node, Conf::STUN_ENABLED_KEY, stunEnabled_);
        parseValue(node, Conf::STUN_SERVER_KEY, stunServer_);
        parseValue(node, Conf::TURN_ENABLED_KEY, turnEnabled_);
        parseValue(node, Conf::TURN_SERVER_KEY, turnServer_);
        parseValue(node, Conf::TURN_SERVER_UNAME_KEY, turnServerUserName_);
        parseValue(node, Conf::TURN_SERVER_PWD_KEY, turnServerPwd_);
        parseValue(node, Conf::TURN_SERVER_REALM_KEY, turnServerRealm_);
    }
}