Serial Port communication program of sending data to DMX 512 receiver - c#

DMX 512 receiver , i need to send data in 512 lines through serial port communication .The problem arises when i need to send data at a baud rate 250000 . Then i used DCB Control block with Getcomm state and Set Comm state . and then i writefile but should i use comPort.Write (Serial comPort = new Serial Port) to send data or WriteFile .This is my below program
I have a VB.Net program of Serial Port communication program of sending data to DMX 512 receiver which i need to convert into c# . But i am confused as they have used MSCOMM1.OUTPUT to send data .
Your help highly appreciated
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public data_array
Private Sub cmd_Start_Click()
setup_com_port
send_comm_data
End Sub
Private Sub cmd_Stop_Click()
If MSComm1.PortOpen = True Then
''MSComm1.PortOpen = False
End
End If
End Sub
Private Sub Form_Load()
data_array = Array(&H7, &H20, &H7)
Slider_Red = &H7
Slider_Green = &H20
Slider_Blue = &H7
End Sub
Private Sub setup_com_port()
MSComm1.CommPort = 2
MSComm1.Settings = "9600,N,8,2"
'MSComm1.InputLen = 0
' MSComm1.InBufferSize = 1024
' MSComm1.OutBufferSize = 1024
MSComm1.PortOpen = True
SetBaudRate MSComm1, 250000
End Sub
' Set baud rate using Win32 API.
' The PortOpen property should be set to True before calling.
' May raise the following errors:
' comPortNotOpen the PortOpen property has not been set to True
' comDCBError failed to read current state of the port
' comSetCommStateFailed failed to set new baud rate
Sub SetBaudRate(Com As MSComm, baud As Long)
Dim ComDcb As dcb
Dim ret As Long
' Check port is open
If Not Com.PortOpen Then
Err.Raise comPortNotOpen, Com.Name, _
"Operation valid only when the port is open"
Exit Sub
End If
' Get existing Comm state
ret = GetCommState(Com.CommID, ComDcb)
If ret = 0 Then
Err.Raise comDCBError, Com.Name, _
"Could not read current state of the port"
Exit Sub
End If
' Modify state with new baud rate
ComDcb.BaudRate = baud
' Set the new Comm state
ret = SetCommState(Com.CommID, ComDcb)
If ret = 0 Then
Err.Raise comSetCommStateFailed, Com.Name, _
"Could not set port to specified baud rate"
Exit Sub
End If
End Sub
Private Sub send_comm_data()
'com_break (10)
Do
com_break (5)
'DoEvents
Sleep (5)
MSComm1.Output = Chr$(0)
'DoEvents
'Sleep (1)
send_char_0
Sleep (10)
DoEvents
Loop
End Sub
Private Sub com_break(break_in_ms)
' Set the Break condition.
MSComm1.Break = True
' Set duration to 1/10 second - 100ms
'Duration! = Timer + (break_in_ms / 100) '0.1 = 100ms
' Wait for the duration to pass.
'Do Until Timer > Duration!
'' Dummy = DoEvents()
'Loop
' Clear the Break condition.
Sleep (1)
MSComm1.Break = False
End Sub
Private Sub send_char_0()
Dim strData As String
strData = ""
For i = 0 To UBound(data_array)
'' MSComm1.Output = Chr$(data_array(i))
strData = strData & Chr$(data_array(i))
Next
For i = 1 To 509
''MSComm1.Output = Chr$(50)
strData = strData & Chr$(50)
Next
MSComm1.Output = strData
7 DoEvents
End Sub
Thanks in advance

I think I got your point since I'm hacking into this for a while now. I found a nice way to send the data correctly. Keep in mind that not all the devices are capable of sending data at 250kbps, so it could be one of your issues. Find the FTDI-based ones to use.
For my approach, we need to send data in two speeds, and this happens because the reset byte must be a zero with a relatively longer time comparing to the other ones. So you will be constantly changing baud rates.
First, configure your device:
var serialPort = new SerialPort("COM0");
serialPort.DataBits = 8;
serialPort.Handshake = Handshake.None;
serialPort.Parity = Parity.None;
serialPort.StopBits = StopBits.Two;
Here I'm starting my serial port instance with all that config you've done too. Don't forget to change the COM port to fit your needs.
Now let's say you have two byte arrays, one for the "big zero" and another for the actual information:
byte[] zero = new byte[] { 0x00 };
byte[] buffer = new byte[513];
You'll ask "why 513 bytes for the buffer?", right? Simply because the first byte is a zero that tells that the actual data is going to be sent. (from 1 to 513, so there are 512 channels)
And finally the main loop: (I obviously recommend for you to do this in a separate thread)
while (true)
{
serialPort.BaudRate = 96000;
serialPort.Write(zero, 0, zero.Length);
serialPort.BaudRate = 250000;
serialPort.Write(buffer, 0, buffer.Length);
Thread.Sleep(50);
}
Now I need your help to test it. I'm not confident that it will work flawlessly for longer times without damaging the IC, but I tried it for two hours and nothing harmful happened. Could you test it longer and send me a feedback? I would appreciate it very much. Does anyone have another approach without the need of changing the baud rates?

Related

SSL_connect() fail on WinCE 5.0

I used OpenSSL 1.0.2j to develop a desktop email client application with no
problems. I copied the code from my desktop to a WinCE 5.0 device .NET CF 2.0.
The connection SSL_connect() alway fails with a value of 5 (SSL_ERROR_SYSCALL).
A call to CE's GetLastError() on gives me an error 10038 (WSAENOTSOCK Socket operation on nonsocket).
Do you have any suggestions? what might be causing this problem?
Thanks in advance
Here's the code:
SSL_library_init()
OPENSSL_add_all_algorithms_noconf()
Dim sslCtx As IntPtr = SSL_CTX_new(SSLv23_client_method())
Dim ssl_socket As IntPtr = SSL_new(sslCtx)
Dim sbioPtr As IntPtr = BIO_new_socket(mySocket.Handle, 0)
SSL_set_bio(ssl_socket, sbioPtr, sbioPtr)
Dim connOK As Integer = SSL_connect(ssl_socket)
If connOK = 1 Then
.....
Else
MsgBox("OpenSSL's SSL_connect() failed")
Dim errcode As Integer = SSL_get_error(ssl_socket, connOK)
MsgBox("SSL Error: " + errcode.ToString)
If errcode = 5 Then
MsgBox("GLE = " + Runtime.InteropServices.Marshal.GetLastWin32Error.ToString)
End If
End If
mySocket.Close()
Else
MsgBox("Socket's connect() failed")
End If
Socket's handle create using CompactFramework on WinCE has always value greater than Int (max value expected on ' BIO_new_socket ')

List each IP from UDP Broadcast

So I'm building a small little program to send out/receive a UDP broadcast. I realize that UDP is not recommended but I won't know the IP address.
Here is what the client is sending out:
'Send "Hello Message" to ALL UDPListners
Public Sub UDPSendHello()
Dim client As New UDPClient()
Dim ip As New IPEndPoint(IPAddress.Broadcast, 15000)
Dim bytes As Byte() = Encoding.ASCII.GetBytes("Hello?")
client.Send(bytes, bytes.Length, ip)
client.Close()
End Sub
For the Server, I get the message "hello" and find the IP address like so:
'Reciever (Server)
Private ReadOnly udp As New UdpClient(15000)
Public Sub UDPHelloListner()
udp.BeginReceive(AddressOf Receive, New Object())
End Sub
Private Sub Receive(ByVal ar As IAsyncResult)
Dim ip As New IPEndPoint(IPAddress.Any, 15000)
Dim bytes As Byte() = udp.EndReceive(ar, ip)
Dim message As String = Encoding.ASCII.GetString(bytes)
If message = "Hello?" Then
Dim sender As New IPEndPoint(IPAddress.Any, 15000)
Dim senderRemote As EndPoint = CType(sender, EndPoint)
My.Settings.clientIPAddress = (ip.AddressFamily.ToString() + ip.Address.ToString)
MessageBox.Show(My.Settings.clientIPAddress)
' ListBox1.Items.Add(My.Settings.clientIPAddress)
End If
UDPHelloListner()
End Sub
Now I can use MessageBox.Show(My.Settings.clientIPAddress) to show the IP address of the client who is sending the message. So the above WORKS!
Now if I had 4 instances of this program broadcasting the above as a Client. How could I list each IP of those 4 instances that are running the client? I used ' ListBox1.Items.Add(My.Settings.clientIPAddress) but it says that "The calling thread cannot access this object because a different thread owns it."
If you use WPF try this:
Dispatcher.Invoke(Sub() ListBox1.Items.Add(My.Settings.clientIPAddress))
If you use WinForms:
Invoke(Sub() ListBox1.Items.Add(My.Settings.clientIPAddress))
In both cases I mean that your code is in Window class.

SMTP Repeater loger

I'm trying to do a repeater (as a proxy) for logging the data exchange between a SMTP client and a server. I thought it was only easy as:
Listening the client;
Listening client IP connection;
On call, connect to the server;
Send back server message;
Send the client messages to the server and return the server feedback to the client;
But, as I saw, some servers as MS exchange send multiple feedback witch are breaking the handshaking.Like:
250-SIZE 41943040
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-STARTTLS
250-AUTH LOGIN
250-8BITMIME
250-BINARYMIME
250 CHUNKING
Here is the class
Imports System.Text
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Public Class SmtpProxy
Private client As TcpClient
Private cltstream As NetworkStream
Private cltreader As System.IO.StreamReader
Private cltwriter As System.IO.StreamWriter
Private smtpserver As New TcpClient
Private srvstream As NetworkStream
Private srvreader As System.IO.StreamReader
Private srvwriter As System.IO.StreamWriter
Private Shared mHostSrv As String
Public Shared Property HostSrv() As String
Get
Return mHostSrv
End Get
Set(ByVal value As String)
mHostSrv = value
End Set
End Property
Private Shared mServerPort As Integer = 25
Public Shared Property ServerPort() As Integer
Get
Return mServerPort
End Get
Set(ByVal value As Integer
)
mServerPort = value
End Set
End Property
Private Shared mUserNm As String
Public Shared Property UserNm() As String
Get
Return mUserNm
End Get
Set(ByVal value As String)
mUserNm = value
End Set
End Property
Private Shared mPassword As String
Public Shared Property Password() As String
Get
Return mPassword
End Get
Set(ByVal value As String)
mPassword = value
End Set
End Property
Public Sub New(ByVal client As TcpClient)
Me.client = client
cltstream = client.GetStream()
cltreader = New System.IO.StreamReader(cltstream)
cltwriter = New System.IO.StreamWriter(cltstream)
cltwriter.NewLine = vbCr & vbLf
cltwriter.AutoFlush = True
End Sub
Public Shared Sub Start() 'ByVal args As String())
Dim listener As New TcpListener(IPAddress.Loopback, 2525)
listener.Start()
While True
Dim handler As New SmtpProxy(listener.AcceptTcpClient())
Dim thread As Thread = New System.Threading.Thread(New ThreadStart(AddressOf handler.Run))
thread.Start()
End While
End Sub
Public Sub Run()
If mHostSrv Like "*.*.*.*" Then
Dim IpS As IPAddress = Nothing
IpS = IPAddress.Parse(mHostSrv)
smtpserver.Connect(IpS, mServerPort)
Else
smtpserver.Connect(mHostSrv, mServerPort)
End If
srvstream = smtpserver.GetStream
srvreader = New System.IO.StreamReader(srvstream)
srvwriter = New System.IO.StreamWriter(srvstream)
srvwriter.NewLine = vbCrLf
srvwriter.AutoFlush = True
Dim srvline As String = srvreader.ReadLine
cltwriter.WriteLine(srvline)
Debug.Print("Server sent: {0}", srvline & vbCrLf)
Try
Dim line As String = cltreader.ReadLine
While line IsNot Nothing
Debug.Print("Read line {0}", line)
srvwriter.WriteLine(line)
Application.DoEvents()
srvline = srvreader.ReadLine()
Debug.Print("Server sent: {0}", srvline)
cltwriter.WriteLine(srvline.Replace("-", " "))
Application.DoEvents()
line = cltreader.ReadLine()
End While
Catch ex As Exception
client.Close()
smtpserver.Close()
End Try
End Sub
End Class
I tried to read multiple server lines at a time but in the meantime the client return and error if I send the whole returned server lines...
Private Function ReadSrvLines() As String
Dim strRet As String = ""
Do
If strRet Like "220*" OrElse srvreader.EndOfStream Then Exit Do
Dim strTmp As String = srvreader.ReadLine
If strTmp Is Nothing Then Exit Do
strRet &= strTmp.Replace("-", " ") & vbCrLf
cltwriter.WriteLine(strTmp.Replace("-", " "))
Debug.Print("Server sent: {0}", strTmp.Replace("-", " ") & vbCrLf)
Loop
Return strRet
End Function
Then is anyone have any solutions to propose?
Thanks all!!
Frank
You will need to perform simultaneous asynchronous reading/writing between client and server to make this work properly. SMTP responses can contain any number of lines and client or server can return a message without the need for a command (to say bye for example). Parsing the data is also unnecessary to achieve a basic log.
Edit: If it helps, if the 3 digit message number if followed by a (minus) rather than a (space) it means that there is another line to follow.

How to dial phone from a .NET website? Very old solution works, need to upgrade to server control

Currently, we have a website that relies on a Microsoft TAPI interface to dial a phone from within a .NET web site. It uses VBScript and tags, and it is bound to a master page. What we are looking for is a server control that would encompass all of this code and only be ran when it is included on a webpage.
The old page does the following:
<object classid="clsid:21D6D48E-A88B-11D0-83DD-00AA003CCABD" id="TAPIOBJ"></object>
<object classid="clsid:E9225296-C759-11d1-A02B-00C04FB6809F" id="MAPPER"></object>
After these lines of code are tags that contains VBScript to initialize the Microsoft TAPI 3.0 library and a few functions to dial. A Dialer control creates a call to one of the functions to dial in an onclick event.
Essentially, we want to create the same type of control without having tags embedded into the HTML of a page directly. We also do not want VBScript in there. Ideally, we would like a server control that works with the TAPI 3.0 API and gains access to the client's phone. Is this possible? Since we are talking about a "server" control, I'm skeptical. I could just as easily create a user control within the project, but we'd like to have this in a controls framework for use elsewhere instead of copying it.
I've been looking at this article on how to create a server control for injection of Client ActiveX controls, but is this down the right path?
UPDATE: Here's the VBScript:
This is what sits in the tag:
<script type="text/vbscript" LANGUAGE="VbScript">
'Constants section
'These constants are copied from tapi3if.idl
Const TAPIMEDIATYPE_AUDIO = &H08&
Const TAPIMEDIATYPE_VIDEO = &H8000&
Const S_MEDIA_AUDIOVIDEO = &H8008&
Const TD_CAPTURE = 0
Const TD_RENDER = 1
Const QSL_NEEDED = 1
Const AS_INSERVICE = 0
Const DC_NORMAL = 0
Const TE_CALLSTATE = 8
Const TE_CALLNOTIFICATION = 4
Const CS_DISCONNECTED = 3
Const CS_IDLE = 0
Const CS_OFFERING = 4
Const CS_CONNECTED = 2
Const CNE_OWNER = 0
Const CIS_CALLERIDNAME = 0
Const CIS_CALLERIDNUMBER = 1
'Interface IDs for casting
'Note: you can find the following IID-s in tapi3.h, tapi3if.idl or rend.idl
Const IID_String_ITMediaSupport = "{B1EFC384-9355-11D0-835C-00AA003CCABD}"
Const IID_String_ITTerminalSupport="{B1EFC385-9355-11D0-835C-00AA003CCABD}"
Const IID_String_ITBasicCallControl = "{B1EFC389-9355-11D0-835C-00AA003CCABD}"
'Const IID_String_ITCallInfo = "{B1EFC390-9355-11d0-835C-00AA003CCABD}"
'New interface
Const IID_String_ITCallInfo = "{350F85D1-1227-11D3-83D4-00C04FB6809F}"
Const IID_String_ITStreamControl= "{EE3BD604-3868-11D2-A045-00C04FB6809F}"
Const IID_String_ITDirectoryObjectConference= "{F1029E5D-CB5B-11D0-8D59-00C04FD91AC0}"
Const IID_String_ITCallStateEvent = "{62F47097-95C9-11d0-835D-00AA003CCABD}"
Const IID_String_ITCallNotificationEvent = "{895801DF-3DD6-11d1-8F30-00C04FB6809F}"
' IID of IVideoWindow
' Note: you can find this IID defined in control.h (from your sdk\inc directory),
' which contains the interface to type library QuartzTypeLib for quartz.dll;
' (search for the interface IVideoWindow)
Const IID_String_IVideoWindow = "{56A868B4-0AD4-11CE-B03A-0020AF0BA770}"
' The following CLSID is defined in tapi3.h
'(and it's used for creating a terminal of class "video window terminal")
Const CLSID_String_VideoWindowTerm = "{F7438990-D6EB-11d0-82A6-00AA00B5CA1B}"
'****************************************************************************
'Global variable section
'****************************************************************************
Dim CallStatus
Dim pICallState
pICallState = 0
'Set on True when we are unable to complete the connecting phase, to skip rest of processing
DIM sUnableToComplete
DIM sbNeedToExit
sUnableToComplete = False
sbNeedToExit = False
' If we want to receive incoming calls, we have to register on the corresponding addresses.
'We don't really use the values returned by registration (they are supposed to be used
'for unregistration), because Unregistration is performed automatically when we shutdown the TAPI object
'The variable pRegisteredCallNotification is an array that contains cookies returned by RegisterCallNotifications;
'these would normally be used to call UnregisterNotifications.
'The variable pRegisteredName holds correspondent AddressName
DIM pRegisteredCallNotification(50)
DIM pRegisteredName(50)
DIM iQtaRegistered
DIM callFrom
iQtaRegistered = 0
'Set by radio button "Select Address Type"
DIM sCurrentAddressType
'sCurrentAddressType = -1
sCurrentAddressType = 1
' This variable will hold a reference to the currently established call
DIM spITCall
spITCall = Empty
DIm pVideoWindow1
DIm pVideoWindow2
'Simplest error processing
Sub CheckError(strMsg)
if not Err.number = 0 Then
MsgBox strMsg & ":" & Err.number & ";"&Err.description
sbNeedToExit = True
Err.Clear
End If
End Sub
Function IsComponentInstalled(ProgId)
Dim tmpObject
On Error Resume Next
Set tmpObject = Server.CreateObject(ProgId)
If Err.Number = 0 Then
IsComponentInstalled = True
Else
IsComponentInstalled = False
End If
Set tmpObject = Nothing
End Function
</script>
Below the end body tag after the tags is:
<script type="text/vbscript" LANGUAGE="vbscript">
' Be sure that you call TAPIOBJ.Initialize before window_onload, otherwise you'll
' never receive events from tapi...
On Error Resume Next
call TAPIOBJ.Initialize
sUnableToComplete = False
TAPIOBJ.EventFilter = &H1FFFF&
if Not Err.number = 0 Then
MsgBox "TAPI software has not been installed on your workstation.",0,"Init"
sUnableToComplete = True
End If
For Each pITAddress in TAPIOBJ.Addresses
if left(pITAddress.AddressName,4) <> "Line" and left(pITAddress.AddressName,29) <> "Shoreline Multi-Line Monitor:" _
and pITAddress.MediaTypes = 8 then
callFrom = pITAddress.AddressName
end if
next
'This section shows how to override Application Priority:
'after the execution of the following lines, our app will always receive incoming calls
'even if there are other running tapi apps that had registered for receiving calls before our app.
call TAPIOBJ.SetApplicationPriority("IEXPLORE.EXE",TAPIMEDIATYPE_AUDIO,TRUE)
call TAPIOBJ.SetApplicationPriority("IEXPLORE.EXE",TAPIMEDIATYPE_VIDEO,TRUE)
' Check parameters of a call before connecting it
Sub PressConnect(pNumber,Status)
On Error Resume Next
'MsgBox (pNumber & "," & Status)
DIM iAddressType
DIM pConnectTo
DIM addressFrom
DIM selStr
'If not IsEmpty(spITCall) Then
' MsgBox "You are currently in call. Disconnect first",0,"connect"
'End If
pConnectTo = pNumber
set CallStatus=Status
addressFrom = callFrom
If addressFrom = "" Then
callStatus.innerHTML = "Feature Unavailable"
MsgBox "The TAPI Feature has not been setup on your phone line.",0,"COnnect"
else
sUnableToComplete = False
callStatus.innerHTML = "Connecting to " & pConnectTo & " ...."
'Create new internal call representation
For Each pITAddress in TAPIOBJ.Addresses
if pITAddress.AddressName = addressFrom Then
'Obtain ITMediaSupport
Set pITAddress_Connect = pITAddress
Exit For
End If
Next
Set pITAddress = Nothing
'Create a Call
DIM MediaTypes
MediaTypes = TAPIMEDIATYPE_AUDIO
Set pCall = pITAddress_Connect.CreateCall(pConnectTo,1,MediaTypes)
Set spITCall = pCall
if sUnableToComplete Then
Call DisconnectCall(1)
callStatus.innerHTML = "Call to "& pConnectTo & " failed."
End If
Call pCall.Connect(false)
' Check for error "invalid address" (see in tapi3err.h TAPI_E_INVALADDRESS=(HRESULT)0x8004000C)
if Err.Number = &H8004000C Then
Err.Clear
Call DisconnectCall(1)
callStatus.innerHTML = "Call to "& pConnectTo & " failed: Address is invalid"
Set pCall = Nothing
Else
if not Err.Number = 0 Then
Err.Clear
Call DisconnectCall(1)
callStatus.innerHTML = "Call to "& pConnectTo & " failed: error " & Hex(Err.number)
Set pCall = Nothing
Else
Set spITCall = pCall
End if
End If
end if
Set pCall = Nothing
end sub
' Disconnect current call
Sub HangUp(callDisc)
'On Error resume Next
if not IsEmpty(spITCall) Then
if not callDisc = 8 and not callDisc = 0 Then
' We need some kind of message pump here. The following call to MsgBox does exactly this:
'MsgBox "A call is disconnected",0,"Disconnect"
End If
Set pVideoWindow1 = Nothing
Set pVideoWindow2 = Nothing
' ConnANN.innerHTML = "Disconnected"
if callDisc=0 Then
spITCall.Disconnect(DC_NORMAL)
End If
Set spITCall = Nothing
spITCall = Empty
callStatus.innerHTML = "Disconnected"
'btnDisconnect.disabled = true
'source.visible = false
End If
End Sub
'*****************************************************************************
' Tapi events processing:
' - call state events ("connected", "disconnected")
' - and call notification events (these calls will be in "offering" state)
Sub TAPIOBJ_Event(event_type, tapi_event)
'On Error Resume Next
'Check For disconnected call
if event_type = TE_CALLSTATE Then
DIM pITCallStateEvent
Set pITCallStateEvent = MAPPER.QueryDispatchInterface(_
IID_String_ITCallStateEvent,tapi_event)
iCallState = pITCallStateEvent.State
if iCallState= CS_DISCONNECTED or iCallState= CS_IDLE Then
cause = pITCallStateEvent.Cause
'pICallState=iCallState
strinnerHTML = ""
Select Case cause
Case 1 ' CEC_DISCONNECT_NORMAL - Normal disconnect
strinnerHTML = "Disconnected"
Case 2 ' CEC_DISCONNECT_BUSY
strinnerHTML = "Your Party is busy.Try Later."
Case 3 ' CEC_DISCONNECT_BADADDRESS
strinnerHTML = "Address is invalid"
case 4 ' CEC_DISCONNECT_NOANSWER
strinnerHTML = "No answer from your party."
case 0 'CEC_NONE
strinnerHTML = "No answer from your party."
Case Else
strinnerHTML = "Your call is cancelled, rejected or failed"
End Select
'Call DisconnectCall(1)
'btnDisconnect.disabled = true
End If 'Call is disconnected
if iCallState = CS_CONNECTED Then 'Call is connected
callStatus.innerHTML = "Call is connected."
'btnDisconnect.disabled = False
End If 'Call is connected
End If ' event: call state
'Check only for incoming calls
if event_type = TE_CALLNOTIFICATION Then ' We have an incoming call (an "offering" call)
DIM pITCallNotificationEvent
Set pITCallNotificationEvent = MAPPER.QueryDispatchInterface(_
IID_String_ITCallNotificationEvent,tapi_event)
Call CheckError("TAPIOBJ_Event:query for pITDirectoryObjectUser")
CallOwnership = pITCallNotificationEvent.Event
DIM pITCallInfo
Set pITCallInfo = pITCallNotificationEvent.Call
Call CheckError("TAPIOBJ_Event:get pITCallInfo")
if not blnShowOnlyOnce and pITCallInfo.CallState = CS_OFFERING and not ( CallOwnership = CNE_OWNER) Then
MsgBox "Unable to accept incoming calls: is other instance of this app running?",0,"Info"
blnShowOnlyOnce = True
Exit Sub
End IF
if CallOwnership = CNE_OWNER Then 'We are the owner!
if not IsEmpty(spITCall) Then
MsgBox "Already in call, disconnect first",0,"Incoming Call"
Exit Sub
End if
if pITCallInfo.CallState = CS_OFFERING Then 'Offering
'-- CIS_CALLERIDNAME Wasn't working so I switched to NUMBER
sCalleeName = pITCallInfo.CallInfoString(CIS_CALLERIDNAME)
if not Err.number = 0 then ' Caller ID name is not supported
sCalleeName = "Unknown Name"
Err.Clear
End if
sCalleeNumber = pITCallInfo.CallInfoString(CIS_CALLERIDNUMBER)
if not Err.number = 0 then ' Caller ID name is not supported
sCalleeNumber = "Unknown Number"
Err.Clear
End if
DIM pITCallOffer
Set pITCallOffer = MAPPER.QueryDispatchInterface( _
IID_String_ITBasicCallControl, pITCallInfo)
Call CheckError("TAPIOBJ_Event:query for pITCall")
response = MsgBox("A call from '" & sCalleeNumber & " " & sCalleeName & "' has arrived. Do you want to accept it?",4,"Incoming call")
if not response = 7 Then 'the did not press "NO", so he pressed "YES"
Call AcceptIncomingCall(pITCallOffer, pITCallInfo)
End If
End If 'Call is offering
End If 'We are owner
End If 'Call Notification has arrived
End Sub
</script>
Is it possible to use the ITAPI3 Managed Library to get rid of this and do this in the code-behind?
Hopefully, someone knows of a cleaner, more modern way of doing this, but here's what I did.
I embedded the VBScript into a script server-side, and registered it as a client script. Before I registered it, I added the tags into Literal controls and added them to the Page header. The server control itself was nothing but a link around a phone icon image.
Since I could call VBScript functions inside javascript, I created a GetPhoneNumber function that accepted the controlID of the control where I would get my phone number. This was set on the ControlID property of the Dialer control. In this instance, it was a textbox. The function parses the number for any bad data, then called PressConnect... done. It works, but I'm not really all that pleased with using VBScript in this manner.
If anyone has any idea how to interact with the client (local) TAPI of a user (Actual examples would be appreciated), post them here.

Drive Letter watcher

Instead of the FileSystemWachter Class I am looking something similar that looks when a new drive letter pop-up. For example when a usb disk is attached or an SD-Card is inserted etc you will get a new drive letter. I would like to have an event in my app when this is happening.
Can you use the FileSystemWatcher class for this or is there something specific for this?
Any examples or suggestions?
Try this: http://www.dotnetthoughts.net/2009/02/13/how-to-detect-usb-insertion-and-removal-in-vbnet/
Private WM_DEVICECHANGE As Integer = &H219
Public Enum WM_DEVICECHANGE_WPPARAMS As Integer
DBT_CONFIGCHANGECANCELED = &H19
DBT_CONFIGCHANGED = &H18
DBT_CUSTOMEVENT = &H8006
DBT_DEVICEARRIVAL = &H8000
DBT_DEVICEQUERYREMOVE = &H8001
DBT_DEVICEQUERYREMOVEFAILED = &H8002
DBT_DEVICEREMOVECOMPLETE = &H8004
DBT_DEVICEREMOVEPENDING = &H8003
DBT_DEVICETYPESPECIFIC = &H8005
DBT_DEVNODES_CHANGED = &H7
DBT_QUERYCHANGECONFIG = &H17
DBT_USERDEFINED = &HFFFF
End Enum
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If m.Msg = WM_DEVICECHANGE Then
Select Case m.WParam
Case WM_DEVICECHANGE_WPPARAMS.DBT_DEVICEARRIVAL
lblMessage.Text = "USB Inserted"
Case WM_DEVICECHANGE_WPPARAMS.DBT_DEVICEREMOVECOMPLETE
lblMessage.Text = "USB Removed"
End Select
End If
MyBase.WndProc(m)
End Sub
One solution can be WMI, especially the
Computer System Hardware Classes
Here is a solution using a timer. This is not specific to USB type devices.
Dim WithEvents myTimer As New Timers.Timer
Private Sub Form1_Shown(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Shown
'start a timer to watch for new drives
myTimer.Interval = 1000
myTimer.AutoReset = True
myTimer.Start()
drvs.AddRange(IO.Directory.GetLogicalDrives) 'get initial set of drives
End Sub
Dim drvs As New List(Of String)
Private Sub myTimer_Elapsed(ByVal sender As Object, _
ByVal e As System.Timers.ElapsedEventArgs) Handles myTimer.Elapsed
Dim cDrvs As New List(Of String)(IO.Directory.GetLogicalDrives) 'get current drives
Dim eDrvs As IEnumerable(Of String)
Dim add_or_remove As Integer = 0 '0 = same number, 1 = removed, 2 = add
If cDrvs.Count = drvs.Count Then
'same number of drives - check that they are the same
eDrvs = drvs.Except(cDrvs)
ElseIf cDrvs.Count < drvs.Count Then
'drive(s) removed
eDrvs = drvs.Except(cDrvs)
add_or_remove = 1
Debug.WriteLine("R")
ElseIf cDrvs.Count > drvs.Count Then
'new drive(s)
eDrvs = cDrvs.Except(drvs)
add_or_remove = 2
Debug.WriteLine("A")
End If
For Each d As String In eDrvs
Debug.WriteLine(d)
Next
drvs = cDrvs 'set list of current drives
End Sub

Categories

Resources