public static extern Int32 lineMakeCall(
     // Açık olan hatta ait handle
     IntPtr hLine,
     // Çağrıya ait handle (fonksiyon başarılıysa).
     ref IntPtr lphCall,
     // Telefon numarası
     string lpszDestAddress,
     // Ülke kodu. Sıfır girilirse, varsayılan kullanılır.
     UInt32 dwCountryCode,
     // LINECALLPARAMS yapısı.
     // Boş girilirse, 3.1 kHz sesli arama/çağrı yapılacağı varsayılır.
     LINECALLPARAMS lpCallParams);
 public static extern Int32 lineOpen(
     // TAPI ait handle.
     IntPtr hLineApp,
     // Açılacak hattın tanıtıcı nosu.
     UInt32 dwDeviceID,
     // Açılan hatta ait handle
     ref IntPtr hLine,
     // TAPI versiyonu
     UInt32 dwAPIVersion,
     // dwExtVersion: Özel kullanım. Sıfır değeri verilebilir.
     UInt32 dwExtVersion,
     // Geri çağrılır fonksiyon nesnesi (TAPI tarafından yorumlanmaz)
     LineCallback dwCallbackInstance,
     // Uygulamanın çağrıyla ilgili ayrıcalıklarının parametresi
     Enums.LineCallPrivilege dwPrivileges,
     // Çağrı ortamıyla ilgili parametre.
     Enums.LineMediaMode dwMediaModes,
     // LINECALLPARAMS yapısı
     LINECALLPARAMS lpCallParams);
        }//GetDecoder

        // İlk önce bir hat açan ve daha sonra bir telefon araması yapan metodumuz.
        // sLineName:    hat adı
        // sPhoneNumber: telefon numarası
        public bool OpenLineDevice(string sLineName, string sPhoneNumber)
        {
            // Hat açıksa, CloseLine metodu çağrılarak hat kaptılıyor.
            if (CloseLine() == TAPI_SUCCESS)
            {
                // Bir LineClass nesnesi tanımlıyoruz ve
                // hattın sınıf değişkenlerine - özelliklerine erişmek için
                // GetLineByName metodunu çağırıyoruz.
                LineClass lnc = GetLineByName(sLineName);

                // LineClass nesnesi null mu?
                if ((lnc == null))
                {
                    return(false);
                }

                // LINECALLPARAMS yapı nesnesi tanımlıyoruz.
                LINECALLPARAMS callParams = new LINECALLPARAMS();

                // Hat açmak için lineOpen fonksiyonunu çağırıyoruz.
                // Fonksiyondan dönen değer, iRetVal değişkenine atanır.
                Int32 iRetVal = lineOpen(this.m_hLineApp,
                                         lnc.LineDevID,
                                         ref this.m_hLine,
                                         lnc.TAPIVer,
                                         0,
                                         this.m_CallBack,
                                         Enums.LineCallPrivilege.LINECALLPRIVILEGE_NONE,
                                         Enums.LineMediaMode.LINEMEDIAMODE_INTERACTIVEVOICE,
                                         callParams);

                // Fonksiyon çağrısı başarılı mı?
                if (iRetVal == TAPI_SUCCESS)
                {
                    // CallStatusDialogEvent nesnesine OnCallStatusDialogEvent metodu adresi atanıyor.
                    CallStatusDialogEvent += new
                                             CallStatusDialogEventHandler(OnCallStatusDialogEvent);

                    //frmMain.ShowStatusMsg("Hat açıldı." + "\r\n");

                    // sPhoneNumber değişkeni boşsa sadece çevir sesi alınır.
                    // Boş değilse, bir telefon numarasını çevirerek arama yapar.
                    iRetVal = lineMakeCall(m_hLine, ref m_hCall, sPhoneNumber, 0, null);

                    if (iRetVal > 0)
                    {
                        // Telefonla arama başlatma başarılı olursa, bu LINE_REPLY olayı ile bildirilir.
                        // Geriye dönen pozitif tanıtıcı değer, LineCallbackEventHandler metodu içinde kullanılması için
                        // m_iPlaceCallIdt değişkenine atanır.
                        this.m_iPlaceCallIdt = iRetVal;

                        return(true);
                    }
                    else
                    {
                        return(false);
                    }//if
                }
                else
                {
                    // lineOpen fonksiyonu çağrısı başarısız.
                    //MessageBox.Show("Hat daha önce başka bir uygulama veya servis sağlayıcısı tarafından açılmış.");

                    return(false);
                }//if lineOpen
            }
            else
            {
                return(false);
            } //if
        }     //OpenLineDevice
        static internal IntPtr ProcessCallParams(int addressId, MakeCallParams param, int callFlags)
        {
            IntPtr lpCp = IntPtr.Zero;

            if (param != null)
            {
                var lcp = new LINECALLPARAMS
                {
                    dwBearerMode     = (int)param.BearerMode,
                    dwMinRate        = param.MinRate,
                    dwMaxRate        = param.MaxRate,
                    dwMediaMode      = (int)param.MediaMode,
                    dwCallParamFlags = callFlags
                };

                if (param.BlockCallerId)
                {
                    lcp.dwCallParamFlags |= NativeMethods.LINECALLPARAMFLAGS_BLOCKID;
                }
                if (param.TakeDestinationOffhook)
                {
                    lcp.dwCallParamFlags |= NativeMethods.LINECALLPARAMFLAGS_DESTOFFHOOK;
                }
                if (param.TakeOriginationOffhook)
                {
                    lcp.dwCallParamFlags |= NativeMethods.LINECALLPARAMFLAGS_ORIGOFFHOOK;
                }
                if (param.OriginateOnIdleCall)
                {
                    lcp.dwCallParamFlags |= NativeMethods.LINECALLPARAMFLAGS_IDLE;
                }
                if (param.WantSecureCall)
                {
                    lcp.dwCallParamFlags |= NativeMethods.LINECALLPARAMFLAGS_SECURE;
                }
                if (param.WantPredictiveDialing)
                {
                    lcp.dwCallParamFlags |= NativeMethods.LINECALLPARAMFLAGS_PREDICTIVEDIAL;
                }

                lcp.dwUserUserInfoSize           = (param.UserUserInfo == null) ? 0 : param.UserUserInfo.Length;
                lcp.dwNoAnswerTimeout            = param.NoAnswerTimeout;
                lcp.dwOrigAddressSize            = String.IsNullOrEmpty(param.OriginationAddress) ? 0 : param.OriginationAddress.Length;
                lcp.dwTargetAddressSize          = String.IsNullOrEmpty(param.TargetAddress) ? 0 : param.TargetAddress.Length;
                lcp.dwAddressMode                = NativeMethods.LINEADDRESSMODE_ADDRESSID;
                lcp.dwAddressID                  = addressId;
                lcp.DialParams.dwDialPause       = param.DialPause;
                lcp.DialParams.dwDialSpeed       = param.DialSpeed;
                lcp.DialParams.dwDigitDuration   = param.DigitDuration;
                lcp.DialParams.dwWaitForDialtone = param.WaitForDialtoneDuration;

                lcp.dwTotalSize = Marshal.SizeOf(lcp);
                if (lcp.dwUserUserInfoSize > 0)
                {
                    lcp.dwUserUserInfoOffset = lcp.dwTotalSize;
                    lcp.dwTotalSize         += lcp.dwUserUserInfoSize;
                }
                if (lcp.dwOrigAddressSize > 0)
                {
                    lcp.dwOrigAddressOffset = lcp.dwTotalSize;
                    lcp.dwTotalSize        += lcp.dwOrigAddressSize;
                }
                if (lcp.dwTargetAddressSize > 0)
                {
                    lcp.dwTargetAddressOffset = lcp.dwTotalSize;
                    lcp.dwTotalSize          += lcp.dwTargetAddressSize;
                }

                lpCp = Marshal.AllocHGlobal(lcp.dwTotalSize);
                Marshal.StructureToPtr(lcp, lpCp, true);
                if (lcp.dwUserUserInfoSize > 0)
                {
                    NativeMethods.WriteByteArray(param.UserUserInfo, lpCp, lcp.dwUserUserInfoOffset);
                }
                if (lcp.dwOrigAddressSize > 0 && param.OriginationAddress != null)
                {
                    NativeMethods.WriteByteArray(Encoding.Default.GetBytes(param.OriginationAddress), lpCp, lcp.dwOrigAddressOffset);
                }
                if (lcp.dwTargetAddressSize > 0 && param.TargetAddress != null)
                {
                    NativeMethods.WriteByteArray(Encoding.Default.GetBytes(param.TargetAddress), lpCp, lcp.dwTargetAddressOffset);
                }
            }

            return(lpCp);
        }