/// <summary> /// This method is used to establish a conference call /// </summary> /// <param name="conferenceCount"># of parties anticipated the conference</param> /// <param name="mcp">Call parameters for created consultation call</param> /// <param name="consultCall">Returning consultation call</param> /// <returns>Conference call</returns> public ITapiCall SetupConference(int conferenceCount, MakeCallParams mcp, out TapiCall consultCall) { IntPtr lpCp = IntPtr.Zero; int callFlags = 0; try { if (mcp != null && !String.IsNullOrEmpty(mcp.TargetAddress)) { callFlags |= NativeMethods.LINECALLPARAMFLAGS_NOHOLDCONFERENCE; } lpCp = MakeCallParams.ProcessCallParams(Id, mcp, callFlags); uint hCall, hConfCall; int rc = NativeMethods.lineSetupConference(new HTCALL(), _lineOwner.Handle, out hConfCall, out hCall, conferenceCount, lpCp); if (rc < 0) { throw new TapiException("lineSetupConference failed", rc); } else { // Wait for the LINE_REPLY so we don't need to deal with the value type // issues of IntPtr being filled in async. var req = new PendingTapiRequest(rc, null, null); _lineOwner.TapiManager.AddAsyncRequest(req); req.AsyncWaitHandle.WaitOne(); if (req.Result < 0) { throw new TapiException("lineSetupConference failed", req.Result); } if (hCall != 0) { consultCall = new TapiCall(this, hCall); AddCall(consultCall); } else { consultCall = null; } var confCall = new TapiCall(this, hConfCall); AddCall(confCall); return(confCall); } } finally { if (lpCp != IntPtr.Zero) { Marshal.FreeHGlobal(lpCp); } } }
/// <summary> /// This forwards calls destined for this address according to the specified forwarding instructions. /// Any specified incoming calls for that address are deflected to the other number by the switch. /// This function provides a combination of forward and do-not-disturb features. /// </summary> /// <param name="forwardInstructions">The forwarding instructions to apply</param> /// <param name="numRingsNoAnswer">Number of rings before a call is considered a "no answer." If dwNumRingsNoAnswer is out of range, the actual value is set to the nearest value in the allowable range.</param> /// <param name="param">Optional call parameters - only used if a consultation call is returned; otherwise ignored. May be null for default parameters</param> public ITapiCall Forward(ForwardInfo[] forwardInstructions, int numRingsNoAnswer, MakeCallParams param) { if (!Line.IsOpen) { throw new TapiException("Line is not open", NativeMethods.LINEERR_OPERATIONUNAVAIL); } IntPtr lpCp = IntPtr.Zero; IntPtr fwdList = ForwardInfo.ProcessForwardList(forwardInstructions); try { lpCp = MakeCallParams.ProcessCallParams(_addressId, param, 0); uint hCall; int rc = NativeMethods.lineForward(_lineOwner.Handle, 0, _addressId, fwdList, numRingsNoAnswer, out hCall, lpCp); if (rc < 0) { throw new TapiException("lineForward failed", rc); } else { // Wait for the LINE_REPLY so we don't need to deal with the value type // issues of IntPtr being filled in async. var req = new PendingTapiRequest(rc, null, null); _lineOwner.TapiManager.AddAsyncRequest(req); req.AsyncWaitHandle.WaitOne(); if (req.Result < 0) { throw new TapiException("lineForward failed", req.Result); } if (hCall != 0) { var call = new TapiCall(this, hCall); AddCall(call); return(call); } } } finally { if (lpCp != IntPtr.Zero) { Marshal.FreeHGlobal(lpCp); } if (fwdList != IntPtr.Zero) { Marshal.FreeHGlobal(fwdList); } } return(null); }
/// <summary> /// Places a new call on the address /// </summary> /// <param name="address">Number to dial</param> /// <param name="countryCode">Country code</param> /// <param name="param">Optional <see>MakeCallParams</see> to use while dialing</param> /// <returns>New <see cref="TapiCall"/> object.</returns> public ITapiCall MakeCall(string address, int countryCode, MakeCallParams param) { if (!Line.IsOpen) { throw new TapiException("Line is not open", NativeMethods.LINEERR_OPERATIONUNAVAIL); } IntPtr lpCp = IntPtr.Zero; try { lpCp = MakeCallParams.ProcessCallParams(_addressId, param, 0); uint hCall; int rc = NativeMethods.lineMakeCall(_lineOwner.Handle, out hCall, address, countryCode, lpCp); if (rc < 0) { throw new TapiException("lineMakeCall failed", rc); } else { // Wait for the LINE_REPLY so we don't need to deal with the value type // issues of IntPtr being filled in async. var req = new PendingTapiRequest(rc, null, null); _lineOwner.TapiManager.AddAsyncRequest(req); req.AsyncWaitHandle.WaitOne(); if (req.Result < 0) { throw new TapiException("lineMakeCall failed", req.Result); } var call = new TapiCall(this, hCall); AddCall(call); return(call); } } finally { if (lpCp != IntPtr.Zero) { Marshal.FreeHGlobal(lpCp); } } }
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); }