Issue in configuring a TAPI address line - tapi

I am developing a telephony application with TAPI API's. I am able to get some sample codes to develop an Application using TAPI API's, but I am not able to configure Address for the TAPI application to work. Any help would be of greatly appreciated.
Thanks,
Ganesan S
Adding piece of code , which I have tried
private int InitializePhoneDevices()
{
var parms = new PHONEINITIALIZEEXPARAMS();
parms.dwTotalSize = parms.dwNeededSize = parms.dwUsedSize = Marshal.SizeOf(parms);
parms.dwOptions = NativeMethods.PHONEINITIALIZEEXOPTION_USEEVENT;
parms.dwCompletionKey = 0;
parms.hEvent = IntPtr.Zero;
int numDevices; uint hTapi;
int rc = NativeMethods.phoneInitializeEx(out hTapi, 0, null, _appName,
out numDevices, ref _phoneVersion, ref parms);
if (rc == NativeMethods.PHONEERR_OK)
{
_hTapiPhone = new HTPHONEAPP(hTapi, true);
_evtReceivedPhoneEvent.SafeWaitHandle = new SafeWaitHandle(parms.hEvent, false);
_phoneArray = new List<TapiPhone>();
for (int i = 0; i < numDevices; i++)
{
_phoneArray.Add(new TapiPhone(this, i));
}
}
else
{
numDevices = 0;
}
return numDevices;
}
The number of devices in the list is always coming as empty, that is the problem, what configurations I have top do in my system to get it populated.

Are you certain your PBX is exposing via Phone Devices? In my experience most TAPI 2.2 drivers will expose via Line Devices. Try using lineInitializeEx instead.
MSDN lineInitializeEx function

Related

Use Redemption and Profman to add Exchange Online mailbox to existing profile

I'm trying to use Redemption and Profman to add an Exchange Online mailbox to an existing Outlook profile. I want to simulate the same result as when you use File | Add Account in Outlook. (I don't want to add a delegate mailbox.)
I've written some code (it's below), but I can't get it to work. I am testing with an email account that I have no problem adding manually. When I use the File | Add Account in Outlook, a screen pops up that asks me for an email address. I enter the email address, and the account is successfully added to my profile. I don't even need to enter a password.
However, when I use the code below for the same email address, it doesn't work. The mailbox shows up in Outlook, but when I click on it, I get the message: "The set of folders cannot be opened. The attempt to log on to Microsoft Exchange has failed". And there is no prompt for me to enter a password.
I'm using Outlook 2021. The code below was adapted from:
https://www.dimastr.com/redemption/profman_examples.htm#ROH_Profile_Outlook2016
private static void AddExoMailbox(string profileName, string email)
{
const int PR_DISPLAY_NAME_W = 0x3001001F;
const int PR_PROFILE_USER_SMTP_EMAIL_ADDRESS_W = 0x6641001F;
const int PR_EMSMDB_SECTION_UID = 0x3D150102;
const int PR_STORE_PROVIDERS = 0x3D000102;
var profile = new ProfMan.Profiles().Item[profileName];
var ExchService = profile.Services.Add("MSEMS", "Microsoft Exchange", false);
var vProfileGuid = ExchService.ProfSect.Item[PR_EMSMDB_SECTION_UID];
dynamic ProviderStoreUid = null;
for (int k = 1; k <= ExchService.Providers.Count; k++)
{
var ExProvider = ExchService.Providers.Item[k];
var ProviderUid = ExProvider.UID;
if (ProviderUid == vProfileGuid)
{
var ProviderProfSect = ExProvider.ProfSect;
ProviderProfSect.Item[PR_PROFILE_USER_SMTP_EMAIL_ADDRESS_W] = $"SMTP:{email}";
ProviderStoreUid = ExchService.ProfSect.Item[PR_STORE_PROVIDERS];
}
}
for (int k = 1; k <= ExchService.Providers.Count; k++)
{
var ExProvider = ExchService.Providers.Item[k];
var ProviderUid = ExProvider.UID;
if (ProviderUid == ProviderStoreUid)
{
var StoreProviderProfSect = ExProvider.ProfSect;
StoreProviderProfSect.Item[PR_DISPLAY_NAME_W] = email;
StoreProviderProfSect.Item[PR_PROFILE_USER_SMTP_EMAIL_ADDRESS_W] = $"SMTP:{email}";
}
}
}
Any pointers?

How to get a device's serial no with Nativescript?

Does anybody know how to get the serial number of a device?
I know I can do this in a NativeScript-5 application (TypeScript):
import { Page } from "tns-core-modules/ui/page";
import * as platformModule from "tns-core-modules/platform";
export function onNavigatingTo(args: EventData) {
let page = <Page>args.object;
console.log("Manufacturer:" + platformModule.device.manufacturer);
console.log("Model:" + platformModule.device.model);
console.log("UUID:" + platformModule.device.uuid);
}
But I couldnt find any property for the device's serial number.
Anybody an idea? It's alright if your solution only covers Android (since my project is targeting Android tablets only).
Thanks!
Update:
Manoj pointed me to some Java code that probably solves my problem. However, I wasn't able to marshal the following code to TypeScript.
public static String getManufacturerSerialNumber() {
String serial = null;
try {
Class<?> c = Class.forName("android.os.SystemProperties");
Method get = c.getMethod("get", String.class, String.class);
serial = (String) get.invoke(c, "ril.serialnumber", "unknown");
} catch (Exception ignored) {}
return serial;
}
Maybe anybody could help me? That would be awesome!
iOS never allows any confidential information to be accessed by apps, that applies to serial number too. With Android, you may read the serial number with
android.os.Build.SERIAL
I had it tested with Playground
Edit 1:
Manufactures like Samsung seems to have a different serial number which is not same as android.os.Build.SERIAL. Here is another SO thread that seems very relevant for Samsung, the sample code is written in Java.
Edit 2:
Here is how you may get serial number on Samsung devices
let serialNumber = '';
try {
const cl = application.android.context.getClassLoader();
const SystemProperties = cl.loadClass('android.os.SystemProperties');
const paramTypes = (<any>Array).create(java.lang.Class, 2);
paramTypes[0] = java.lang.String.class;
paramTypes[1] = java.lang.String.class;
const getMethod = SystemProperties.getMethod('get', paramTypes);
const params = (<any>Array).create(java.lang.Object, 2);
params[0] = new java.lang.String('ril.serialnumber');
params[1] = new java.lang.String('unknown');
serialNumber = getMethod.invoke(SystemProperties, params);
} catch (err) {
console.error(err);
}
Updated Playground
You can check properties 'ro.serialno', 'ril.serialnumber', 'gsm.sn1', 'sys.serialnumber'
Android: How to programmatically access the device serial number shown in the AVD manager (API Version 8)
In my case Samsung TAB S2 has 2 serials. Property 'ro.serialno' more accurate then 'ril.serialnumber'. So i check it first.
getSerial() {
if (isAndroid) {
let serialNumber = null;
try {
const cl = application.android.context.getClassLoader();
const SystemProperties = cl.loadClass('android.os.SystemProperties');
const paramTypes = (<any>Array).create(java.lang.Class, 2);
paramTypes[0] = java.lang.String.class;
paramTypes[1] = java.lang.String.class;
const getMethod = SystemProperties.getMethod('get', paramTypes);
const params = (<any>Array).create(java.lang.Object, 2);
// Reorder if needed
const props = ['ro.serialno', 'ril.serialnumber', 'gsm.sn1', 'sys.serialnumber'];
for(let i = 0, len = props.length; i < len; i++) {
params[0] = new java.lang.String(props[i]);
serialNumber = getMethod.invoke(SystemProperties, params);
if (serialNumber !== '') {
return serialNumber;
}
}
} catch (err) {
console.error(err);
}
return serialNumber;
}
}
Full code: https://play.nativescript.org/?template=play-tsc&id=ViNo6g&v=6

EWS The server cannot service this request right now

I am seeing errors while exporting email in office 365 account using ews managed api, "The server cannot service this request right now. Try again later." Why is that error occurring and what can be done about it?
I am using the following code for that work:-
_GetEmail = (EmailMessage)item;
bool isread = _GetEmail.IsRead;
sub = _GetEmail.Subject;
fold = folder.DisplayName;
historicalDate = _GetEmail.DateTimeSent.Subtract(folder.Service.TimeZone.GetUtcOffset(_GetEmail.DateTimeSent));
props = new PropertySet(EmailMessageSchema.MimeContent);
var email = EmailMessage.Bind(_source, item.Id, props);
bytes = new byte[email.MimeContent.Content.Length];
fs = new MemoryStream(bytes, 0, email.MimeContent.Content.Length, true);
fs.Write(email.MimeContent.Content, 0, email.MimeContent.Content.Length);
Demail = new EmailMessage(_destination);
Demail.MimeContent = new MimeContent("UTF-8", bytes);
// 'SetExtendedProperty' used to maintain historical date of items
Demail.SetExtendedProperty(new ExtendedPropertyDefinition(57, MapiPropertyType.SystemTime), historicalDate);
// PR_MESSAGE_DELIVERY_TIME
Demail.SetExtendedProperty(new ExtendedPropertyDefinition(3590, MapiPropertyType.SystemTime), historicalDate);
if (isread == false)
{
Demail.IsRead = isread;
}
if (_source.RequestedServerVersion == flagVersion && _destination.RequestedServerVersion == flagVersion)
{
Demail.Flag = _GetEmail.Flag;
}
_lstdestmail.Add(Demail);
_objtask = new TaskStatu();
_objtask.TaskId = _taskid;
_objtask.SubTaskId = subtaskid;
_objtask.FolderId = Convert.ToInt64(folderId);
_objtask.SourceItemId = Convert.ToString(_GetEmail.InternetMessageId.ToString());
_objtask.DestinationEmail = Convert.ToString(_fromEmail);
_objtask.CreatedOn = DateTime.UtcNow;
_objtask.IsSubFolder = false;
_objtask.FolderName = fold;
_objdbcontext.TaskStatus.Add(_objtask);
try
{
if (counter == countGroup)
{
Demails = new EmailMessage(_destination);
Demails.Service.CreateItems(_lstdestmail, _destinationFolder.Id, MessageDisposition.SaveOnly, SendInvitationsMode.SendToNone);
_objdbcontext.SaveChanges();
counter = 0;
_lstdestmail.Clear();
}
}
catch (Exception ex)
{
ClouldErrorLog.CreateError(_taskid, subtaskid, ex.Message + GetLineNumber(ex, _taskid, subtaskid), CreateInnerException(sub, fold, historicalDate));
counter = 0;
_lstdestmail.Clear();
continue;
}
This error occurs only if try to export in office 365 accounts and works fine in case of outlook 2010, 2013, 2016 etc..
Usually this is the case when exceed the EWS throttling in Exchange. It is explain in here.
Make sure you already knew throttling policies and your code comply with them.
You can find throttling policies using Get-ThrottlingPolicy if you have the server.
One way to solve the throttling issue you are experiencing is to implement paging instead of requesting all items in one go. You can refer to this link.
For instance:
using Microsoft.Exchange.WebServices.Data;
static void PageSearchItems(ExchangeService service, WellKnownFolderName folder)
{
int pageSize = 5;
int offset = 0;
// Request one more item than your actual pageSize.
// This will be used to detect a change to the result
// set while paging.
ItemView view = new ItemView(pageSize + 1, offset);
view.PropertySet = new PropertySet(ItemSchema.Subject);
view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);
view.Traversal = ItemTraversal.Shallow;
bool moreItems = true;
ItemId anchorId = null;
while (moreItems)
{
try
{
FindItemsResults<Item> results = service.FindItems(folder, view);
moreItems = results.MoreAvailable;
if (moreItems && anchorId != null)
{
// Check the first result to make sure it matches
// the last result (anchor) from the previous page.
// If it doesn't, that means that something was added
// or deleted since you started the search.
if (results.Items.First<Item>().Id != anchorId)
{
Console.WriteLine("The collection has changed while paging. Some results may be missed.");
}
}
if (moreItems)
view.Offset += pageSize;
anchorId = results.Items.Last<Item>().Id;
// Because you’re including an additional item on the end of your results
// as an anchor, you don't want to display it.
// Set the number to loop as the smaller value between
// the number of items in the collection and the page size.
int displayCount = results.Items.Count > pageSize ? pageSize : results.Items.Count;
for (int i = 0; i < displayCount; i++)
{
Item item = results.Items[i];
Console.WriteLine("Subject: {0}", item.Subject);
Console.WriteLine("Id: {0}\n", item.Id.ToString());
}
}
catch (Exception ex)
{
Console.WriteLine("Exception while paging results: {0}", ex.Message);
}
}
}

XNA 4.0 Spritbatch - render target must not be set on the device

i am converting a XNA 3.0 cloud effect into XNA 4.0 but i get an error
"The render target must not be set on the device when it is used as a texture."
It happens in the second loop in this line:
mover.Parameters["PressureMap"].SetValue(PressureOffsets);
Code:
for (int i = 0; i < 10; i++)
{
graf.SetRenderTarget(rt5);
mover.Parameters["PressureMap"].SetValue(PressureOffsets);
mover.Parameters["DivergenceMap"].SetValue(Divergence);
mover.CurrentTechnique = mover.Techniques["Jacobi"];
mover.CurrentTechnique.Passes[0].Apply();
sp.Begin(SpriteSortMode.Deferred, BlendState.Opaque, SamplerState.PointWrap, DepthStencilState.DepthRead, RasterizerState.CullNone);
sp.Draw(Velocity, new Vector2(0, 0), Color.White);
sp.End();
graf.SetRenderTarget(null);
PressureOffsets = rt5;
}
It seems I cant set in XNA 4.0 an texture as an effect parameter, if its already set as rendertarget.
But I dont know how to convert this to work in XNA 4.0 :(
I solved it.
Its necessary to change the rendertarget with a new one.
I used a helper Class "RenderTargetState".
public RenderTargetState SetToDevice()
{
oldState = new RenderTargetState(GraphicsDevice);
GraphicsDevice.SetRenderTarget(new RenderTarget2D(GraphicsDevice, renderTargetWidth, renderTargetHeight));
return oldState;
}
public RenderTargetState BeginRenderToTexture()
{
oldState = SetToDevice();
return oldState;
}
public Texture2D EndRenderGetTexture()
{
RenderTargetState renderBuffer = oldState.SetToDevice();
oldState = null;
return renderBuffer.RenderTarget;
}
So the code looks like this now:
for (int i = 0; i < 10; i++)
{
rt5.BeginRenderToTexture();
graf.SetRenderTarget(rt5.RenderTarget);
mover.Parameters["PressureMap"].SetValue(PressureOffsets);
mover.Parameters["DivergenceMap"].SetValue(Divergence);
mover.CurrentTechnique = mover.Techniques["Jacobi"];
mover.CurrentTechnique.Passes[0].Apply();
sp.Begin(SpriteSortMode.Deferred, BlendState.Opaque);
sp.Draw(Velocity, new Vector2(0, 0), Color.White);
sp.End();
graf.SetRenderTarget(null);
PressureOffsets = rt5.EndRenderGetTexture();
}
There's an easier way to do this.
rt5 = PressureOffsets as RenderTarget2D
graf.SetRenderTarget(null);
PressureOffsets = rt5;

How to programmatically query if an SCCM 2012 Application is Active or Retired

We have an application that integrates with SCCM 2012 and saves custom SCCM applications to SCCM.
The problem I am having is that attempting to save one of our custom applications when the SCCM administrator has set the application to be in the retired state causes our application to fail the saving process.
I'd like to be able to query the SCCM application state in order to determine before we attempt the save operation whether the given application is Active or Retired.
I can find no reference to "retired" status in the SMS_Application Server WMI help or any of the other pages:
http://msdn.microsoft.com/en-us/library/hh949251.aspx
I have noticed that there is a Restore() method which looks like it will change the status of a Retired package back to Active, however that's not quite what I want to do.
Can anyone help me determine how to find an applications current status?
Thanks.
There's a method in the SCCM 2012 PowerShell cmdlets that appears to be retrieving the expired status. Here's the c# code (decompiled from the dll AppUI.PS.AppMan.dll on the SCCM server)
private bool IsApplicationRetired(IResultObject applicaction)
{
IResultObject[] resultObjectArray = null;
int integerValue = applicaction["CI_ID"].IntegerValue;
object[] objArray = new object[] { integerValue };
resultObjectArray = base.ExecuteQuery(string.Format(CultureInfo.InvariantCulture, "SELECT * FROM SMS_Application WHERE CI_ID = {0}", objArray));
IResultObject[] resultObjectArray1 = resultObjectArray;
int num = 0;
if (num < (int)resultObjectArray1.Length)
{
IResultObject resultObject = resultObjectArray1[num];
this.isApplicationRetired = resultObject["IsExpired"].BooleanValue;
}
if (this.isApplicationRetired)
{
object[] objArray1 = new object[] { integerValue };
IResultObject instance = base.ConnectionManager.GetInstance(string.Format(CultureInfo.InvariantCulture, "SMS_Application.CI_ID={0}", objArray1));
if (instance != null)
{
string stringValue = instance["ModelName"].StringValue;
instance.Dispose();
object[] objArray2 = new object[] { base.ConnectionManager.EscapeQueryString(stringValue, ConnectionManagerBase.EscapeQuoteType.SingleQuote) };
resultObjectArray = base.ExecuteQuery(string.Format(CultureInfo.InvariantCulture, "SELECT CI_ID FROM SMS_Application WHERE ModelName = '{0}' AND IsLatest = 1 AND IsExpired = 0", objArray2));
IResultObject[] resultObjectArray2 = resultObjectArray;
int num1 = 0;
if (num1 < (int)resultObjectArray2.Length)
{
IResultObject resultObject1 = resultObjectArray2[num1];
if (resultObject1["CI_ID"].IntegerValue != integerValue)
{
this.isApplicationRetired = false;
}
}
}
}
return this.isApplicationRetired;
}

Resources