Friday, June 23, 2006

Koneksi GPRS dengan TcpClient

201114333 - Slamet Adi Wiyono
========================
dotNET Compact Framework

HttpWebRequest pada NETCF (dotnet Compact Framework) secara otomatis membuat hubungan GPRS untuk request web/web servis ketika koneksi wired/wi-fi tidak tersedia. Oleh karena itu, ketika melakukan web request atau menggunakan sebuah web servis, para developer tidak membutuhkan kode khusus untuk menangani kasus koneksi GPRS. Hal ini tidak diaplikasikan ke level class socket yang lebih rendah seperti TcpClient dan UdpClient. Class-class di bawah ini akan diperlukan untuk Connection Manager API sebagai koneksi menggunakan GPRS.

Untuk dapat memungkinkan user agar lebih mudah membuat koneksi GPRS, dibawah telah dituliskan untuk merepresentasikan dari Connection Manager API yang dibutuhkan ketika akan membuat suatu koneksi GPRS dengan TcpClient

sourcec code :

/*--------------------------------------------------------*/
public class GPRSConnection{
const int S_OK = 0;
const uint CONNMGR_PARAM_GUIDDESTNET = 0x1;
const uint CONNMGR_FLAG_PROXY_HTTP = 0x1;
const uint CONNMGR_PRIORITY_USERINTERACTIVE = 0x08000;
const uint INFINITE = 0xffffffff;
const uint CONNMGR_STATUS_CONNECTED = 0x10;
static Hashtable ht = new Hashtable();

static GPRSConnection()
{
ManualResetEvent mre = new ManualResetEvent(false);
mre.Handle = ConnMgrApiReadyEvent();
mre.WaitOne();
CloseHandle(mre.Handle);
}

~GPRSConnection(){
ReleaseAll();
}

public static bool Setup(Uri url){
return Setup(url.ToString());
}

public static bool Setup(string urlStr)
{
ConnectionInfo ci = new ConnectionInfo();
IntPtr phConnection = IntPtr.Zero;
uint status = 0;
if (ht[urlStr] != null)
return true;
if (ConnMgrMapURL(urlStr, ref ci.guidDestNet,
IntPtr.Zero) != S_OK)
return false;

ci.cbSize = (uint) Marshal.SizeOf(ci);
ci.dwParams = CONNMGR_PARAM_GUIDDESTNET;
ci.dwFlags = CONNMGR_FLAG_PROXY_HTTP;
ci.dwPriority = CONNMGR_PRIORITY_USERINTERACTIVE;
ci.bExclusive = 0;
ci.bDisabled = 0;
ci.hWnd = IntPtr.Zero;
ci.uMsg = 0;
ci.lParam = 0;
if (ConnMgrEstablishConnectionSync
(ref ci,ref phConnection,INFINITE,ref status)!=S_OK &&

status != CONNMGR_STATUS_CONNECTED)
return false;
ht[urlStr] = phConnection;
return true;
}

public static bool Release(Uri url){
return Release(url.ToString());
}

public static bool Release(string urlStr)
{
return Release(urlStr, true);
}

private static bool Release(string urlStr, bool removeNode)
{
bool res = true;
IntPtr ph = IntPtr.Zero;
if (ht[urlStr] == null)
return true;
ph = (IntPtr)ht[urlStr];
if (ConnMgrReleaseConnection(ph, 1) != S_OK)
res = false;
CloseHandle(ph);
if (removeNode)
ht.Remove(urlStr);
return res;
}

public static void ReleaseAll(){
foreach(DictionaryEntry de in ht){
Release((string)de.Key, false);
}
ht.Clear();
}

[StructLayout(LayoutKind.Sequential)]
public struct ConnectionInfo
{
public uint cbSize;
public uint dwParams;
public uint dwFlags;
public uint dwPriority;
public int bExclusive;
public int bDisabled;
public Guid guidDestNet;
public IntPtr hWnd;
public uint uMsg;
public uint lParam;
public uint ulMaxCost;
public uint ulMinRcvBw;
public uint ulMaxConnLatency;
}
 [DllImport("cellcore.dll")]
private static extern int ConnMgrMapURL
(string pwszURL, ref Guid pguid, IntPtr pdwIndex);

[DllImport("cellcore.dll")]
private static extern int ConnMgrEstablishConnectionSync
(ref ConnectionInfo ci, ref IntPtr phConnection,
uint dwTimeout, ref uint pdwStatus);
 [DllImport("cellcore.dll")]
private static extern IntPtr ConnMgrApiReadyEvent();
 [DllImport("cellcore.dll")]
private static extern int ConnMgrReleaseConnection
(IntPtr hConnection, int bCache);
 [DllImport("coredll.dll")]
private static extern int CloseHandle(IntPtr hObject);
}

/*--------------------------------------------------------------------*/

Menggunakan class GPRSConnection sangat mudah yakni memanggil method setup sebelum membuat koneksi dengan class TcpClient. Anda bisa menggunakan contoh dibawah sebagai referensi untuk melihat bagaimana class tersebut digunakan.

/*============================================================*/
public void DoTcpConnection(){
string url = "www.msn.com";
bool res = GPRSConnection.Setup("http://" + url + "/");
if (res){
TcpClient tc = new TcpClient(url, 80);
NetworkStream ns = tc.GetStream();
byte[] buf = new byte[100];
ns.Write(buf, 0, 100);
tc.Client.Shutdown(SocketShutdown.Both);
ns.Close();
tc.Close();
MessageBox.Show("Wrote 100 bytes");
}
else{
MessageBox.Show("Connection establishment failed");
}
}

/*======================================================*/

Sebagai tambahan, struktur dibawah adalah cara yang biasa dilakukan untuk koneksi General Packet Radio Service (GPRS) yang digunakan pada saat awal dari pemanggilan GPRS. Hal dibawah ini adalah profile khusus yang digunakan untuk koneksi GPRS. Untuk membuat sebuah koneksi, karakter dalam string GPRS_DEST_ADDRESS harus merupakan bagian dari string yang dikirimkan untuk lineMakeCall. Hal ini akan memulai koneksi GPRS, aplikasikan parameter-parameter dalam struktur dibawah. String untuk dial digunakan dan disesuaikan berdasarkan aplikasi yang memiliki control yang lengkap melalui parameter GPRS.

typedef struct cellgprsconnectioninfo_tag {
DWORD dwProtocolType;
DWORD dwL2ProtocolType
WCHAR wszAccessPointName[CELLDEVCONFIG_MAXLENGTH_GPRSACCESSPOINTNAME];
WCHAR wszAddress[CELLDEVCONFIG_MAXLENGTH_GPRSADDRESS;
DWORD dwDataCompression;
DWORD dwHeaderCompression;
char szParameters[CELLDEVCONFIG_MAXLENGTH_GPRSPARAMETERS;
BOOL bRequestedQOSSettingsValid;
CELLGPRSQOSSETTINGS cgqsRequestedQOSSettings;
BOOL bMinimumQOSSettingsValid;
CELLGPRSQOSSETTINGS cgqsMinimumQOSSettings;
} CELLGPRSCONNECTIONINFO, *LPCELLGPRSCONNECTIONINFO;

Keterangan :

dwProtocolType
Identitas tipe protocol untuk koneksi GPRS. Gunakan salah satu nilai dari nilai yang terdapat pada tabel.

dwL2ProtocolType
Identitas dari tipe protocol level-2 untuk koneksi GPRS.

wszAccessPointName
Nama yang spesifik yang digunakan untuk memilih gateway GPRS

wszAddress
Menentukan alamat address yang dipakai untuk koneksi. Jika strirng ini empty/kosong, akan digunakan sebuah alamat yang dynamic/random.

dwDataCompression
Identitas setting kompresi data untuk pesan yang akan dikirim dan diterima.

dwHeaderCompression
Identitas setting kompresi data untuk pesan yang dikirm dan diterima. Untuk daftar nilai yang mungkin, dapat melihat daftar nilai untuk dwDataCompression

szParameters
Identitas parameter protocol-spesifik. Harus diisi dengan NULL untuk terminated

bRequestedQOSSettingsValid
TRUE jika dan hanya jika cgqsRequestedQOSSettings adalah valid

cgqsRequestedQOSSettings
Struktur setting kualitas servis (QOS) dari GPRS.
Jika bRequestedQOSSettingsValid adalah TRUE, cgqsRequestedQOSSettings yang digunakan;
Jika bRequestedQOSSettingsValid bernilai FALSE, cgqsRequestedQOSSettings tidak digunakan.

bMinimumQOSSettingsValid
TRUE jika dan hanya jika cgqsMinimumQOSSettings adalah valid

cgqsMinimumQOSSettings
Struktur setting QOS GPRS.
Jika bMinimumQOSSettingsValid bernilai TRUE, maka cgqsMinimumQOSSettings yang digunakan;
Jika bMinimumQOSSettingsValid bernilai FALSE, maka cgqsMinimumQOSSettings tidak digunakan.

Sumber :
1.http://blogs.msdn.com/anthonywong/archive/2006/03/13/550686.aspx
2.http://msdn.microsoft.com/library/default.asp?url=/library/en-us/apisp/html/sp_tsp_cellgprsconnectioninfo.asp

No comments: