This is all very frustrating! I have an "ez_tapi.dll" from Paul Vangelderp and it works a treat for eVB but I can not seem to use it in C#.
If anybody feel inspired they can test this themselves: the zipped attachment contains Paul's DLL code (C++ project) and his small test project (eVB), which proves that the DLL works well. Also included is my micky-mouse C# test project: I can dial up a modem and establish a GSM/V.110 connection, but when I try to send data by calling Ez_tapi_UTransmit() the application blows. I am assuming we have a problem passing the string between managed and unmanaged code.
I have buggered about with every imaginable combination of ref and out (the C# equivalent of ByVal and ByRef) for both Unicode and with byte/char arrays - all I ever get is the totally unhelpful "NotSupportedException". Is this a marshaling issue and if so how can I fix it?
Any help would be most welcome - I think Paul is planning on offering his DLL as a general purpose encapsulation of TAPI for application programmers who only need to quickly make a dial-up data connection for their PocketPC projects... once we have got it working!
Best regards,
Peter Beedell.
Re:
You can wrap library in this method:
//Function to Dial up a telephone number and get a Comm Handle
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_UDial")]
private static extern int TAPIUDial(string szPhoneNumber);
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_Dial")]
private static extern int TAPIDial(string szPhoneNumber);
//Function to Return the Current Tapi Status
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_Status")]
private static extern uint TAPIStatus();
// Function to Return the TAPI handle
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_Handle")]
private static extern uint TapiHandle();
//Function to close line and release all handles
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_Shutdown")]
private static extern bool TapiShutDown();
//Transmit a Unicode string
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_UTransmit")]
private static extern bool TapiUTransmit(string txData, uint size);
//Transmit a Transmit a char (Byte) string
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_Transmit")]
private static extern bool TapiTransmit(string txData, uint size);
//Receive a Unicode string
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_UReceive")]
private static extern uint TapiUReceive(string rxData, uint size);
//Receive a Receive a char (byte) string
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_Receive")]
private static extern uint TapiReceive(string rxData);
// Return how many characters are waiting in the buffer
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_Rx_Count")]
private static extern uint TapiRxCount();
//Wait for a Unicode Text String with timeout value
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_UWait")]
private static extern bool TapiUWait(string What, uint length, uint Timeout);
//Wait for a char (byte) Text String with timeout value
[DllImport("ez_tapi.dll", EntryPoint = "Ez_tapi_Wait")]
private static extern bool TapiWait(string What, uint length, uint Timeout);
bye
Related
Hi All,
My app is required to update certain information to my server every 15mins or so. This data is being successfully posted, however on reviewing my phone bill, the code is forcing a new GPRS connection with each post.
I use the ConnectionManager API to get a handle to the optimal/current connection:
Code:
DWORD dwCurrentStatus;
ConnMgrConnectionStatus(hConnection, &dwCurrentStatus);
if (dwCurrentStatus != CONNMGR_STATUS_CONNECTED){
ConnMgrEstablishConnectionSync(&sCI, &hConnection, 30000, &dwStatus);
}
// Make outgoing internet connection.
hInternetSession = InternetOpen(TEXT("My App"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
// Connect to the server
hServerSession = InternetConnect(hInternetSession, szServer, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, NULL, NULL);
if(hInternetSession == NULL || hServerSession == NULL){
return false;
}
After each post I close the internet handle ( I am fairly sure this shouldn't drop the GPRS connection):
Code:
InternetCloseHandle(hHttpSession);
InternetCloseHandle(hServerSession);
InternetCloseHandle(hInternetSession);
hHttpSession = NULL;
hServerSession = NULL;
hInternetSession = NULL;
On application SHUTDOWN I allow the connection to close:
Code:
ConnMgrReleaseConnection(hConnection, 0);
if(hConnection){
hConnection = NULL;
}
InternetCloseHandle(hHttpSession);
InternetCloseHandle(hServerSession);
InternetCloseHandle(hInternetSession);
hHttpSession = NULL;
hServerSession = NULL;
hInternetSession = NULL;
Has anyone else had similar problems or is aware of what I am doing wrong?
Cheers
gprs connection
i have a small app that changes gprs connection when one of them is down, but i have found that the connmgrreleaseconnection call does not work, and the current connection will not die, you may have the same problem
I am in need of some help.
I need to be able to utilize the Win32 SendMessage API (via C#) to Ignore/Answer phone calls on a whim. The current test bed is Windows Mobile 5.0, and from what I have been able to gather, the program that I should be sending the message to is cprog.exe. So the question is, should I be sending anything other than the WM_LBUTTONDOWN, WM_RBUTTONDOWN events in order to do so?
Code:
public class Message
{
public const int WM_LBUTTONDOWN = 0x0201;
public const int WM_RBUTTONDOWN = 0x0204;
}
[DllImport("coredll.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);
...
Win32.SendMessage(pc.Handle, Win32.Message.WM_RBUTTONDOWN, 0, 0);
Well if you just want an app that will auto send a txt to a phone call that you can't answer, it's in the forums, Mobile Secretary. And yes, I believe from what your doing cprog.exe is the phone application.
I did a search in the forum, and didn't see if this is mentioned, so forgive me if this has been discussed.
I am trying to programatically send an SMS to a normal email address... and I know the phone can do it (AT&T Tilt, AT&T service), as I can do it manually. My first approach (as to not start monkeying around with the MAPI stuff) is to try the SMS API (sms.h and sms.lib). I am trying to use the SmsSendMessage function. My code works great for messages to other phones, but fails with the very informative return code of E_FAIL when sending to a "normal" email address.
Is there a trick or a setting that I am missing?
Here is a code sample of what I am trying to do:
Code:
BOOL CSMSSender::Send( wchar_t *message )
{
if( message == NULL )
{
return FALSE;
}
SMS_HANDLE smsHandle;
SMS_ADDRESS source;
SMS_ADDRESS dest;
TEXT_PROVIDER_SPECIFIC_DATA textData;
SMS_MESSAGE_ID messageId;
HRESULT result = S_OK;
BOOL retVal = TRUE;
result = SmsOpen( SMS_MSGTYPE_TEXT, SMS_MODE_SEND, &smsHandle, NULL );
if( result != S_OK )
{
return FALSE;
}
// Setup source address...
dest.smsatAddressType = SMSAT_UNKNOWN;
_tcsncpy( dest.ptsAddress, GetSmsAddr( ), SMS_MAX_ADDRESS_LENGTH );
// Setup the provider information...
memset( &textData, 0, sizeof( textData ) );
textData.dwMessageOptions = PS_MESSAGE_OPTION_NONE; // No confirmation...
textData.psMessageClass = PS_MESSAGE_CLASS1;
textData.psReplaceOption = PSRO_NONE;
textData.dwHeaderDataSize = 0;
result = SmsSendMessage( smsHandle,
NULL,
&dest,
NULL,
(PBYTE) message,
_tcslen( message ) * sizeof (wchar_t),
(PBYTE) &textData,
sizeof( TEXT_PROVIDER_SPECIFIC_DATA ),
SMSDE_OPTIMAL,
SMS_OPTION_DELIVERY_NONE,
&messageId );
if( result != S_OK )
{
retVal = FALSE;
goto EXIT;
}
EXIT:
result = SmsClose( smsHandle );
if( result != S_OK )
{
retVal = FALSE;
}
return retVal;
}
You can probably guess that GetSmsAddr( ) returns a wchar_t * that is the address I am trying to send it to. When it is a phone number, works swimmingly, when it is a "normal" email address, it fails. This is, of course, a snippet of a much larger system, but the only SMS specific stuff, and the stuff that gives me the problems. So, if you wonder "why did he do it this way", probably stuff missing that would make it more clear.
If the answer is to go swimming in the mess that is MAPI, then so be it... but would like to know if there is an easier answer before I put on my trunks...
Take Care,
Wicked96SS
Found the solution... I feel dumb... It is actually pretty easy. The provider is the one that does the conversion from SMS to "normal" email. And you have to send the SMS to the email gateway. The SMS has to be specially formatted. Here is a non comprehensive list of the formats expected by certain vendors:
Format (Carrier;SMS to Email Gateway Number;Text Format)
AT&T (Formerly Cingular) USA;111 or 121;emailaddress (subject) text
CTI (Argentina);6425;emailaddress (subject) text
Swisscom Mobile AG (only Switzerland);555;<emailaddress> <subject>/<text>
T-Mobile Austria http://t-mobile.at;6761;<emailaddress> <text>
T-Mobile (USA);500;<emailaddress> / <subject> / <text>
Anyhow, still looking for Verizon and some others, but i am sure they are simple.
So, if configured like that, and sent to the correct number, I do get SMS messages to normal email accounts.
Code snippet for AT&T
Code:
result = SmsOpen( SMS_MSGTYPE_TEXT, SMS_MODE_SEND, &smsHandle, NULL );
if( result != S_OK )
{
return SMS_INIT_FAILED;
}
// Setup source address...
dest.smsatAddressType = SMSAT_UNKNOWN;
_tcsncpy( dest.ptsAddress, L"111", SMS_MAX_ADDRESS_LENGTH );
// Setup the provider information...
memset( &textData, 0, sizeof( textData ) );
textData.dwMessageOptions = PS_MESSAGE_OPTION_NONE; // No confirmation...
textData.psMessageClass = PS_MESSAGE_CLASS1;
textData.psReplaceOption = PSRO_NONE;
textData.dwHeaderDataSize = 0;
std::wstring body;
body = L"[email protected](Hi!)Here is the body";
result = SmsSendMessage( smsHandle,
NULL,
&dest,
NULL,
(PBYTE) body.c_str( ),
_tcslen( body.c_str( ) ) * sizeof (wchar_t),
(PBYTE) &textData,
sizeof( TEXT_PROVIDER_SPECIFIC_DATA ),
SMSDE_OPTIMAL,
SMS_OPTION_DELIVERY_NONE,
&messageId );
Question on Normal Emails
I found your posting and it works great for sending sms messages to cell phone emails.
I found this link that shows the other gateways you were looking for.
http://en.wikipedia.org/wiki/SMS_gateways
My question is did you ever get this to work to send emails to network email address like [email protected]
let me know if you have any suggestions.
Thanks in Advance
ColoradoGene
hello ColoradoGene! Sorry for the time it took to respond, but yes, I have been able to send SMS messages to email addresses... the message has to be formatted correctly. The source code in my post (#2) will work for AT&T.
What problems are you actually having?
I have tried for some hours now to catch the problem, nowhere are good resources to read.
I have a server application running on my phone (Windows Mobile 6.1)
Binding the TCP Listener to 127.0.0.1ORT does work, if I type the URL from within the device.
Then I tried to connect via WIFI. At first: All WiFi Settings are correct, I know all IPs and pings are possible ... BUT: When I try to access the server from within the wifi network I don't get through. I've bound the listener for testing purposes to 127.0.0.1 and to the IP of my Wifi card. but nothing helped. Is there a kind of firewall or why can't I use a socket connection from PC to PPC?
This should work. I've create a remote-control program via TCP/IP and there were no issues.
Can you post the code for Bind / Listen?
radhoo said:
Can you post the code for Bind / Listen?
Click to expand...
Click to collapse
Code:
byte[] byteBuffer = new byte[1024];
string stringBuffer = null;
[COLOR="Red"] IPAddress localhost = IPAddress.Parse("0.0.0.0");
// I also tried 127.0.0.1 and the IP of my phone in WiFi
TcpListener httpDaemon = new TcpListener(localhost, 80);
httpDaemon.Start();
[/COLOR]
while (true)
{
TcpClient httpBrowser = httpDaemon.AcceptTcpClient();
NetworkStream commStream = httpBrowser.GetStream();
int i;
// Loop to receive all the data sent by the client.
while ((i = commStream.Read(byteBuffer, 0, byteBuffer.Length)) != 0)
{
stringBuffer = System.Text.Encoding.ASCII.GetString(byteBuffer, 0, i);
}
MessageBox.Show(stringBuffer);
httpBrowser.Close();
Provided your code is good, maybe check if the socket is actually listening, there's netstat tool in dotFred's task manager: http://www.dotfred.net/TaskMgr.htm
Furthermore, you can see if the traffic ever reaches your PPC with hSniffer:
http://winm-soft.atspace.com/
You don't seem to be checking any of the return values.
Have you done that?
You might be facing different conditions than when you bind to the loopback adapter.
theq86 said:
Code:
byte[] byteBuffer = new byte[1024];
string stringBuffer = null;
[COLOR="Red"] IPAddress localhost = IPAddress.Parse("0.0.0.0");
// I also tried 127.0.0.1 and the IP of my phone in WiFi
TcpListener httpDaemon = new TcpListener(localhost, 80);
httpDaemon.Start();
[/COLOR]
while (true)
{
TcpClient httpBrowser = httpDaemon.AcceptTcpClient();
NetworkStream commStream = httpBrowser.GetStream();
int i;
// Loop to receive all the data sent by the client.
while ((i = commStream.Read(byteBuffer, 0, byteBuffer.Length)) != 0)
{
stringBuffer = System.Text.Encoding.ASCII.GetString(byteBuffer, 0, i);
}
MessageBox.Show(stringBuffer);
httpBrowser.Close();
Click to expand...
Click to collapse
try other different port rather than http port = 80
mobile phone not design to be a web server.
Code:
I am in a networking course and was assigned a project that we can complete in any language or environment. Being the Android lover that I am I naturally wanted to do this on my phone. The part I am having an issue with should be simple and I am starting to think I can not establish a connection using UDP between the phones. What I am trying to do is use one phone as a server and one as a client. The client sends a message to the server and the server changes the string to upper case. (this is not the project, but a good step to see if it is working.) Does anyone know why the server and client would not be connecting or if it is even possible?
This is the server, below is the client, main launch screen, and main.xml
Code:
package com.csc.networking;
import java.net.*;
import android.util.Log;
public class UDPServer
{
public void main() throws Exception
{
Log.d("s","1");
DatagramSocket serverSocket = new DatagramSocket(6699);//create a datagram socket at the specified port number
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
Log.d("s","2");
while(true)
{
Log.d("s","3");
DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
//To Do: construct a DatagramPacket object called receivePacket. Use the constructor of the class DatagramPacket
//that takes two parameters: 1. the array of bytes (receiveData) and 2. the length of that array.
Log.d("s","3.5");
//To Do: use the method receive on the DatagramSocket object to receive the packet sent from the client.
//the method receive takes one parameter (the DatagramPacket object constructed in the above step).
serverSocket.receive(receivePacket);
Log.d("s","again");
Log.d("s","3.75");
String sentence = new String(receivePacket.getData());//extract the String from the array of bytes.
Log.d("s",sentence);
Log.d("s","4");
InetAddress IPAddress = receivePacket.getAddress();//extract the IP address of the client
int port = receivePacket.getPort();//extract the port number from the packet
String capitalizedSentence = sentence.toUpperCase();//change the sentence received by the server
sendData = capitalizedSentence.getBytes();//convert it to an array of bytes
Log.d("s","5");
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
//To Do: construct a DatagramPacket object called sendPacket. Use the constructor of the class DatagramPacket
//that takes 4 parameters: 1. the array of bytes to be sent. 2. the length of that array of bytes.
//3. the IP address of the client (use the object IPAddress) and 4. the port number of the process running in
//the client.
//To Do: send the packet to the client using the method send on the DatagramSocket object. The metho send
//takes one parameter which is the packet constructed in the above step.
Log.d("s","5.5");
serverSocket.send(sendPacket );
Log.d("s","6");
}
}
}
Client:
Code:
package com.csc.networking;
import java.io.*;
import java.net.*;
import android.util.Log;
import android.widget.*;
public class UDPClient {
public void main(String string) throws Exception
{
Log.d("help", "1");
//EditText connectAddress = (EditText)findViewById(R.id.connectAddress);
Log.d("help", "2");
String hostIP = "10.60.5.79"; //connectAddress.getText().toString();
Log.d("help", "3");
String coded = string;
Log.d("help", "4");
DatagramSocket clientSocket = new DatagramSocket();//this line creates a datagram socket, this does not
//create a TCP connection with the server, note how we do not have server and process info as parameters to
//the constructor
Log.d("help", "5");
InetAddress IPAddress = InetAddress.getByName(hostIP); //this line invokes DNS to lookup the IP address
//of the hostname. If IP address is provided, it stores it in the object IPAddress.
Log.d("help", "6");
byte[] sendData = new byte[1024]; //array of bytes to be sent to server
Log.d("help", "7");
byte[] receiveData = new byte[1024]; //array of bytes that client will receive from server
Log.d("help", "8");
sendData = coded.getBytes(); //this converts sentence to an array of bytes and stores it in sendData.
Log.d("help", "9");
DatagramPacket sendPacket = new DatagramPacket(sendData,sendData.length,IPAddress,6699);
//To DO: construct a DatagramPacket object called sendPacket. The constructor of the DatagramPacket class
//takes the following parameters: 1. the array of bytes to be sent. 2. the length of the array of bytes.
//3. the IPAddress of the destination (use the object IPAddress) and 4. the port number of the process running
//at the destination.
Log.d("help", "10");
clientSocket.send(sendPacket);
//To DO: call the method send on the DatagramSocket object to send the datagram packet. The method send takes
//the DatagramPacket object as a prameter and sends it through the socket.
Log.d("help", "11");
DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
//To Do: construct a new DatagramPacket object called recievePacket. This is the packet that the client will
//receive from the destination. Use the constructor that takes two parameters: 1. an array of bytes (receiveData) and
//2. the length of that array.
Log.d("help", "12");
clientSocket.receive(receivePacket);
//To Do: use the method receive on the DatagramSocket object to receive the datagram packet from the server.
//The method receive takes a parameter which is the DatagramPacket constructed in the above step.
Log.d("help", "13");
String modifiedSentence = new String(receivePacket.getData());//this converts an array of bytes to a string.
Log.d("help", "14");
TextView decoded = (TextView)findViewById(R.id.decoded);
Log.d("help", "15");
decoded.setText(modifiedSentence);
Log.d("help", "16");
clientSocket.close();//this closes the connection.
Log.d("help", "17");
}
private EditText findViewById(int connectaddress) {
// TODO Auto-generated method stub
return null;
}
}
Code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:baselineAligned="true" android:orientation="vertical"
android:layout_width="wrap_content" android:layout_height="fill_parent">
<TextView android:text="@string/Title" android:id="@+id/Title"
android:layout_width="fill_parent" android:gravity="center"
android:textSize="24px" android:layout_height="wrap_content" />
<EditText android:id="@+id/editText1" android:layout_below="@+id/Title"
android:layout_alignLeft="@+id/Title" android:layout_alignRight="@+id/Title"
android:layout_width="fill_parent"
android:layout_height="wrap_content" android:scrollbarAlwaysDrawVerticalTrack="true" android:scrollbars="vertical" android:singleLine="true" android:hint="@string/Hint"/>
<RelativeLayout android:layout_width="wrap_content"
android:layout_below="@+id/editText1" android:id="@+id/relativeLayout1"
android:layout_height="wrap_content" android:layout_alignLeft="@+id/editText1"
android:layout_alignRight="@+id/editText1">
<Button android:layout_width="wrap_content"
android:layout_below="@+id/startServer" android:layout_height="wrap_content"
android:layout_alignLeft="@+id/startServer"
android:layout_alignRight="@+id/startServer" android:id="@+id/Send"
android:text="@string/Send" />
<EditText android:layout_width="wrap_content" android:layout_below="@+id/Send" android:layout_height="wrap_content" android:layout_alignLeft="@+id/Send" android:layout_alignRight="@+id/Send" android:id="@+id/connectAddress" android:hint="Enter Ip Address Here"></EditText>
<TextView android:text="Decoded" android:layout_width="wrap_content" android:layout_below="@+id/connectAddress" android:id="@+id/decoded" android:layout_height="wrap_content" android:layout_alignLeft="@+id/connectAddress" android:layout_alignRight="@+id/connectAddress"></TextView>
<Button android:layout_width="fill_parent" android:id="@+id/startServer" android:text="@string/Start " android:layout_height="wrap_content" android:layout_alignParentRight="true"></Button>
</RelativeLayout>
</RelativeLayout>
Code:
package com.csc.networking;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class launchScreen extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button SendButton = (Button)findViewById(R.id.Send);
SendButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
Log.d("click", "1");
EditText codedMessage = (EditText)findViewById(R.id.editText1);
UDPClient client = new UDPClient();
String msg = codedMessage.getText().toString();
Log.d("click", msg);
Log.d("click", "2");
client.main(msg);
Log.d("click", "3");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Button ServerButton = (Button)findViewById(R.id.startServer);
ServerButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
UDPServer server = new UDPServer();
server.main();
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
Since your phones actual network is a private network, there's no way to run a server on the phone. Its ports simply won't be available to the outside world. You need some kind of server that is visible to the internet (not firewalled) to marshal the connection between the two phones that are not visible to the internet.
Gene Poole said:
Since your phones actual network is a private network, there's no way to run a server on the phone. Its ports simply won't be available to the outside world. You need some kind of server that is visible to the internet (not firewalled) to marshal the connection between the two phones that are not visible to the internet.
Click to expand...
Click to collapse
Does that mean phone to phone will not work, but phone to stand alone java app will?
What do you mean by stand-alone java app? Phone to self (One app talks UDP to another app on the same phone)?
Phone- computer. Having the server on the computer and the client on the phone.
It is quite possible that the routers on your network don't permit routing packed from one "inside" address to another -- That would mean that you could route packets (through NAT) to the outside world and back again, but not phone-to-phone.
For security reasons, I'd be pretty disappointed to find out that one could route phone-to-phone.