Menulis driver konektor USB Type-C
Anda perlu menulis driver konektor USB Type-C dalam skenario ini:
Jika perangkat keras USB Type-C Anda memiliki kemampuan menangani mesin status pengiriman daya (PD). Jika tidak, pertimbangkan untuk menulis driver pengontrol port USB Type-C. Untuk informasi selengkapnya, lihat Menulis driver pengontrol port USB Type-C.
Jika perangkat keras Anda tidak memiliki pengontrol tertanam. Jika tidak, muat driver dalam kotak yang disediakan Microsoft, UcmUcsi.sys. (Lihat driver UCSI) untuk transportasi ACPI atau tulis driver klien UCSI untuk transportasi non-ACPI.
Ringkasan
- Objek UCM yang digunakan oleh ekstensi kelas dan driver klien
- Layanan yang disediakan oleh ekstensi kelas UCM
- Perilaku driver klien yang diharapkan
Spesifikasi resmi
Berlaku untuk
- Windows 10
Versi WDF
- KMDF versi 1.15
- UMDF versi 2.15
API penting
Menjelaskan manajer konektor USB (UCM) yang mengelola konektor USB Type-C dan perilaku driver konektor yang diharapkan.
UCM dirancang dengan menggunakan model driver klien ekstensi kelas WDF. Ekstensi kelas (UcmCx) adalah driver WDF yang disediakan Microsoft yang menyediakan antarmuka yang dapat dipanggil driver klien untuk melaporkan informasi tentang konektor. Driver klien UCM menggunakan antarmuka perangkat keras konektor dan menjaga ekstensi kelas mengetahui peristiwa yang terjadi pada konektor. Sebaliknya, ekstensi kelas memanggil fungsi panggilan balik yang diterapkan oleh driver klien sebagai respons terhadap peristiwa sistem operasi.
Untuk mengaktifkan konektor USB Type-C pada sistem, Anda harus menulis driver klien.
Sebelum Anda mulai
Instal Windows Driver Kit (WDK) terbaru di komputer pengembangan Anda. Kit ini memiliki file header dan pustaka yang diperlukan untuk menulis driver klien UCM, khususnya, Anda akan memerlukan:
Pustaka stub, (UcmCxstub.lib). Pustaka menerjemahkan panggilan yang dilakukan oleh driver klien dan meneruskannya ke UcmCx.
File header, UcmCx.h.
Anda dapat menulis driver klien UCM yang berjalan dalam mode pengguna atau mode kernel. Untuk mode pengguna, ini mengikat dengan pustaka UMDF 2.x; untuk mode kernel, yaitu KMDF 1.15. Antarmuka pemrograman identik untuk salah satu mode.
Tentukan apakah driver klien Anda akan mendukung fitur lanjutan konektor USB Type-C dan Usb Power Delivery.
Dukungan ini memungkinkan Anda membangun perangkat Windows dengan konektor USB Type-C, dok dan aksesori USB Type-C, dan pengisi daya USB Type-C. Driver klien melaporkan peristiwa konektor yang memungkinkan sistem operasi untuk menerapkan kebijakan sekeliling konsumsi USB dan daya dalam sistem.
Instal Windows 10 untuk edisi desktop (Home, Pro, Enterprise, dan Education) di komputer target Anda atau Windows 10 Mobile dengan konektor USB Type-C.
Biasakan diri Anda dengan UCM dan bagaimana berinteraksi dengan driver Windows lainnya. Lihat Arsitektur: Desain USB Type-C untuk sistem Windows.
Biasakan diri Anda dengan Windows Driver Foundation (WDF). Bacaan yang direkomendasikan: Mengembangkan Driver dengan Windows Driver Foundation, ditulis oleh Penny Orwick dan Guy Smith.
Ringkasan layanan yang disediakan oleh ekstensi kelas UCM
Ekstensi kelas UCM membuat sistem operasi diberitahu tentang perubahan peran data dan daya, tingkat pengisian daya, dan kontrak PD yang dinegosiasikan. Saat driver klien berinteraksi dengan perangkat keras, driver klien harus memberi tahu ekstensi kelas ketika perubahan tersebut terjadi. Ekstensi kelas menyediakan serangkaian metode yang dapat digunakan driver klien untuk mengirim pemberitahuan (dibahas dalam topik ini). Berikut adalah layanan yang disediakan:
Konfigurasi peran data
Pada sistem USB Type-C, peran data (host atau fungsi) tergantung pada status pin CC konektor. Driver klien Anda membaca baris CC (lihat Arsitektur: Status desain USB Type-C untuk sistem Windows) dari pengontrol port Anda untuk menentukan apakah port telah diselesaikan ke Upstream Facing Port (UFP) atau Downstream Facing Port (UFP). Ini melaporkan informasi tersebut ke ekstensi kelas sehingga dapat melaporkan peran saat ini ke driver sakelar peran USB.
Catatan
Driver sakelar peran USB digunakan pada sistem Windows 10 Mobile. Pada Windows 10 untuk sistem edisi desktop, komunikasi antara ekstensi kelas dan driver role-switch bersifat opsional. Sistem tersebut mungkin tidak menggunakan pengontrol peran ganda, dalam hal ini, driver role-switch tidak digunakan.
Peran daya dan pengisian daya
Driver klien Anda membaca iklan USB Type-C saat ini, atau menegosiasikan kontrak daya PD dengan konektor mitra.
- Pada sistem Windows 10 Mobile, keputusan untuk memilih pengisi daya yang sesuai dibantu perangkat lunak. Driver klien melaporkan informasi kontrak ke ekstensi kelas sehingga dapat mengirim tingkat pengisian daya ke driver arbitrase pengisian daya (CAD.sys). CAD memilih tingkat saat ini untuk digunakan dan meneruskan informasi tingkat pengisian daya ke subsistem baterai.
- Pada Windows 10 untuk sistem edisi desktop, pengisi daya yang sesuai dipilih oleh perangkat keras. Driver klien dapat memilih untuk mendapatkan informasi tersebut dan meneruskannya ke ekstensi kelas. Secara bergantian, logika tersebut dapat diimplementasikan oleh driver yang berbeda.
Perubahan peran data dan daya
Setelah kontrak PD dinegosiasikan, peran data dan peran daya mungkin berubah. Perubahan tersebut mungkin dimulai oleh driver klien Atau konektor mitra Anda. Driver klien melaporkan informasi tersebut ke ekstensi kelas, sehingga dapat mengonfigurasi ulang hal-hal yang sesuai.
Pembaruan peran data dan/atau daya
Sistem operasi mungkin memutuskan bahwa peran data saat ini tidak benar. Dalam hal ini ekstensi kelas memanggil fungsi panggilan balik driver Anda untuk melakukan operasi pertukaran peran yang diperlukan.
Manajer Kebijakan USB Type-C yang disediakan Microsoft memantau aktivitas konektor USB Type-C. Windows, versi 1809, memperkenalkan serangkaian antarmuka pemrograman yang dapat Anda gunakan untuk menulis driver klien ke Manajer Kebijakan. Driver klien dapat berpartisipasi dalam keputusan kebijakan untuk konektor USB Type-C. Dengan set ini, Anda dapat memilih untuk menulis driver ekspor mode kernel atau driver mode pengguna. Untuk informasi selengkapnya, lihat Menulis driver klien USB Type-C Policy Manager.
Perilaku driver klien yang diharapkan
Driver klien Anda bertanggung jawab atas tugas-tugas ini:
- Deteksi perubahan pada baris CC dan tentukan jenis mitra, seperti UFP, DFP, dan lainnya. Untuk melakukan ini, driver harus mengimplementasikan mesin status Type-C lengkap seperti yang didefinisikan dalam spesifikasi USB Type-C.
- Konfigurasikan Mux Anda berdasarkan orientasi yang terdeteksi pada baris CC. Ini termasuk mengaktifkan pemancar/penerima PD Anda dan menangani serta merespons pesan PD. Untuk melakukan ini, driver harus mengimplementasikan penerima PD lengkap dan mesin status pemancar seperti yang didefinisikan dalam spesifikasi USB Power Delivery 2.0.
- Buat keputusan kebijakan PD, seperti menegosiasikan kontrak (sebagai sumber atau sink), pertukaran peran, dan lainnya. Driver klien bertanggung jawab untuk menentukan kontrak yang paling tepat.
- Iklankan dan negosiasikan mode alternatif, dan konfigurasikan Mux jika mode alternatif terdeteksi. Driver klien bertanggung jawab untuk memutuskan mode alternatif untuk bernegosiasi.
- Kontrol VBus/VConn melalui konektor.
1. Menginisialisasi objek konektor UCM (UCMCONNECTOR)
Objek konektor UCM (UCMCONNECTOR) mewakili konektor USB Type-C dan merupakan handel utama antara ekstensi kelas UCM dan driver klien. Objek melacak mode operasi konektor dan kemampuan sumber daya.
Berikut adalah ringkasan urutan di mana driver klien mengambil handel UCMCONNECTOR untuk konektor. Lakukan tugas-tugas ini di driver Anda
Panggil UcmInitializeDevice dengan meneruskan referensi ke struktur UCM_MANAGER_CONFIG . Driver harus memanggil metode ini dalam fungsi panggilan balik EVT_WDF_DRIVER_DEVICE_ADD sebelum memanggil WdfDeviceCreate.
Tentukan parameter inisialisasi untuk konektor USB Type-C dalam struktur UCM_CONNECTOR_TYPEC_CONFIG . Ini termasuk mode pengoperasian konektor, baik port yang menghadap ke hilir, port yang menghadap ke hulu, atau berkemampuan peran ganda. Ini juga menentukan tingkat USB Type-C saat ini ketika konektor adalah sumber daya. Konektor USB Type-C dapat dirancang singgah sehingga dapat bertindak sebagai jack audio 3,5 mm. Jika perangkat keras mendukung fitur ini, objek konektor harus diinisialisasi.
Dalam strukturnya, Anda juga harus mendaftarkan fungsi panggilan balik driver klien untuk menangani peran data.
Fungsi panggilan balik ini dikaitkan dengan objek konektor, yang dipanggil oleh ekstensi kelas UCM. Fungsi ini harus diimplementasikan oleh driver klien.
EVT_UCM_CONNECTOR_SET_DATA_ROLE Menukar peran data konektor ke peran yang ditentukan saat dilampirkan ke konektor mitra.
Jika driver klien Anda ingin berkemampuan PD, yaitu, menangani implementasi perangkat keras Power Delivery 2.0 dari konektor, Anda juga harus menginisialisasi struktur UCM_CONNECTOR_PD_CONFIG yang menentukan parameter inisialisasi PD. Ini termasuk aliran daya, apakah konektor adalah power sink atau sumber.
Secara struktur, Anda juga harus mendaftarkan fungsi panggilan balik driver klien untuk menangani peran daya.
Fungsi panggilan balik ini dikaitkan dengan objek konektor, yang dipanggil oleh ekstensi kelas UCM. Fungsi ini harus diimplementasikan oleh driver klien.
EVT_UCM_CONNECTOR_SET_POWER_ROLE Mengatur peran daya konektor ke peran yang ditentukan saat dilampirkan ke konektor mitra.
Panggil UcmConnectorCreate dan ambil handel UCMCONNECTOR untuk konektor. Pastikan Anda memanggil metode ini setelah driver klien membuat objek perangkat kerangka kerja dengan memanggil WdfDeviceCreate. Tempat yang sesuai untuk panggilan ini dapat berada di EVT_WDF_DEVICE_PREPARE_HARDWARE atau EVT_WDF_DEVICE_D0_ENTRY pengemudi.
EVT_UCM_CONNECTOR_SET_DATA_ROLE EvtSetDataRole;
NTSTATUS
EvtDevicePrepareHardware(
WDFDEVICE Device,
WDFCMRESLIST ResourcesRaw,
WDFCMRESLIST ResourcesTranslated
)
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_CONTEXT devCtx;
UCM_MANAGER_CONFIG ucmCfg;
UCM_CONNECTOR_CONFIG connCfg;
UCM_CONNECTOR_TYPEC_CONFIG typeCConfig;
UCM_CONNECTOR_PD_CONFIG pdConfig;
WDF_OBJECT_ATTRIBUTES attr;
PCONNECTOR_CONTEXT connCtx;
UNREFERENCED_PARAMETER(ResourcesRaw);
UNREFERENCED_PARAMETER(ResourcesTranslated);
TRACE_FUNC_ENTRY();
devCtx = GetDeviceContext(Device);
if (devCtx->Connector)
{
goto Exit;
}
//
// Initialize UCM Manager
//
UCM_MANAGER_CONFIG_INIT(&ucmCfg);
status = UcmInitializeDevice(Device, &ucmCfg);
if (!NT_SUCCESS(status))
{
TRACE_ERROR(
"UcmInitializeDevice failed with %!STATUS!.",
status);
goto Exit;
}
TRACE_INFO("UcmInitializeDevice() succeeded.");
//
// Create a USB Type-C connector #0 with PD
//
UCM_CONNECTOR_CONFIG_INIT(&connCfg, 0);
UCM_CONNECTOR_TYPEC_CONFIG_INIT(
&typeCConfig,
UcmTypeCOperatingModeDrp,
UcmTypeCCurrentDefaultUsb | UcmTypeCCurrent1500mA | UcmTypeCCurrent3000mA);
typeCConfig.EvtSetDataRole = EvtSetDataRole;
UCM_CONNECTOR_PD_CONFIG_INIT(&pdConfig, UcmPowerRoleSink | UcmPowerRoleSource);
connCfg.TypeCConfig = &typeCConfig;
connCfg.PdConfig = &pdConfig;
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attr, CONNECTOR_CONTEXT);
status = UcmConnectorCreate(Device, &connCfg, &attr, &devCtx->Connector);
if (!NT_SUCCESS(status))
{
TRACE_ERROR(
"UcmConnectorCreate failed with %!STATUS!.",
status);
goto Exit;
}
connCtx = GetConnectorContext(devCtx->Connector);
UcmEventInitialize(&connCtx->EventSetDataRole);
TRACE_INFO("UcmConnectorCreate() succeeded.");
Exit:
TRACE_FUNC_EXIT();
return status;
}
2. Laporkan peristiwa lampirkan konektor mitra
Driver klien harus memanggil UcmConnectorTypeCAttach saat koneksi ke konektor mitra terdeteksi. Panggilan ini memberi tahu ekstensi kelas UCM, yang selanjutnya memberi tahu sistem operasi. Pada titik ini sistem dapat mulai mengisi daya pada tingkat USB Type-C.
Ekstensi kelas UCM juga memberi tahu driver sakelar peran (URS) USB. Berdasarkan jenis mitra, URS mengonfigurasi pengontrol dalam peran host atau peran fungsi. Sebelum memanggil metode ini, pastikan Mux pada sistem Anda dikonfigurasi dengan benar. Jika tidak, jika sistem berada dalam peran fungsi, sistem akan terhubung pada kecepatan yang salah (berkecepatan tinggi alih-alih SuperSpeed).
UCM_CONNECTOR_TYPEC_ATTACH_PARAMS attachParams;
UCM_CONNECTOR_TYPEC_ATTACH_PARAMS_INIT(
&attachParams,
UcmTypeCPortStateDfp);
attachParams.CurrentAdvertisement = UcmTypeCCurrent1500mA;
status = UcmConnectorTypeCAttach(
Connector,
&attachParams);
if (!NT_SUCCESS(status))
{
TRACE_ERROR(
"UcmConnectorTypeCAttach() failed with %!STATUS!.",
status);
goto Exit;
}
TRACE_INFO("UcmConnectorTypeCAttach() succeeded.");
3. Laporkan perubahan iklan USB Type-C
Dalam peristiwa lampirkan awal, konektor mitra mengirimkan iklan saat ini. Jika iklan menentukan tingkat konektor mitra saat ini saat mitra adalah port yang menghadap ke hilir USB Type-C. Jika tidak, iklan menentukan tingkat konektor lokal saat ini, yang diwakili oleh handel UCMCONNECTOR (konektor lokal). Iklan awal ini mungkin berubah selama masa pakai koneksi. Perubahan tersebut harus dipantau oleh driver klien.
Jika konektor lokal adalah power sink dan iklan saat ini berubah, driver klien harus mendeteksi perubahan dalam iklan saat ini dan melaporkannya ke ekstensi kelas. Pada sistem Windows 10 Mobile, informasi tersebut digunakan oleh CAD.sys dan subsistem baterai untuk menyesuaikan jumlah saat ini yang diambil dari sumbernya. Untuk melaporkan perubahan tingkat saat ini ke ekstensi kelas, driver klien harus memanggil UcmConnectorTypeCurrentAdChanged.
4. Laporkan kontrak PD baru yang dinegosiasikan
Jika konektor Anda mendukung PD, setelah peristiwa lampirkan awal, ada pesan PD yang ditransfer antara konektor dan konektor mitranya. Di antara kedua mitra, kontrak PD dinegosiasikan yang menentukan tingkat saat ini yang dapat digambar konektor atau memungkinkan mitra untuk menggambar. Setiap kali kontrak PD berubah, driver klien harus memanggil metode ini untuk melaporkan perubahan ke ekstensi kelas.
- Driver klien harus memanggil metode ini setiap kali mendapatkan iklan kemampuan sumber (tidak diminta atau sebaliknya) dari mitra. Konektor lokal (sink) mendapatkan iklan yang tidak diminta dari mitra hanya ketika mitra adalah sumbernya. Selain itu, konektor lokal dapat secara eksplisit meminta kemampuan sumber dari mitra yang mampu menjadi sumbernya (bahkan ketika mitra saat ini adalah sink). Pertukaran dilakukan dengan mengirim pesan Get_Source_Caps ke mitra.
- UcmConnectorPdPartnerSourceCaps untuk melaporkan kemampuan sumber yang diiklankan oleh konektor mitra.
- UcmConnectorPdConnectionStateChanged untuk melaporkan detail kontrak. Kontrak dijelaskan dalam Objek Data Permintaan, yang ditentukan dalam spesifikasi Power Delivery 2.0.
- Sebaliknya, driver klien harus memanggil metode ini setiap kali konektor lokal (sumber) mengiklankan kemampuan sumber kepada mitra. Selain itu, ketika konektor lokal menerima pesan Get_Source_Caps dari mitra, konektor lokal harus merespons dengan kemampuan sumber konektor lokal.
- UcmConnectorPdSourceCaps untuk melaporkan kemampuan sumber yang diiklankan oleh sistem ke konektor mitra.
- UcmConnectorPdConnectionStateChanged untuk melaporkan kemampuan koneksi dari kontrak PD yang saat ini dinegosiasikan.
5. Laporkan status pengisian daya baterai
Driver klien dapat memberi tahu ekstensi kelas UCM jika tingkat pengisian daya tidak memadai. Ekstensi kelas melaporkan informasi ini ke sistem operasi. Sistem menggunakan informasi tersebut untuk menunjukkan pemberitahuan pengguna bahwa pengisi daya tidak mengisi daya sistem secara optimal. Status pengisian daya dapat dilaporkan oleh metode ini:
Metode tersebut menentukan status pengisian daya. Jika tingkat yang dilaporkan adalah UcmChargingStateSlowCharging atau UcmChargingStateTrickleCharging (lihat UCM_CHARGING_STATE), sistem operasi menampilkan pemberitahuan pengguna.
6. Melaporkan peristiwa PR_Swap/DR_Swap
Jika konektor menerima pesan pertukaran peran daya (PR_Swap) atau peran data (DR_Swap) dari mitra, driver klien harus memberi tahu ekstensi kelas UCM.
UcmConnectorDataDirectionChanged
Panggil metode ini setelah pesan DR_Swap PD diproses. Setelah panggilan ini, sistem operasi melaporkan peran baru ke URS, yang merobek driver peran yang ada dan memuat driver untuk peran baru.
UcmConnectorPowerDirectionChanged
Panggil metode ini setelah pesan PR_Swap PD diproses. Setelah PR_Swap, kontrak PD perlu dinegosiasikan ulang. Driver klien harus melaporkan bahwa negosiasi kontrak PD dengan memanggil metode yang dijelaskan di langkah 4.
7. Menerapkan fungsi panggilan balik untuk menangani permintaan pertukaran peran daya dan data
Ekstensi kelas UCM mungkin mendapatkan permintaan untuk mengubah data atau arah daya konektor. Dalam hal ini, ini memanggil implementasi driver klien dari fungsi panggilan balik EVT_UCM_CONNECTOR_SET_DATA_ROLE dan EVT_UCM_CONNECTOR_SET_POWER_ROLE (jika konektor mengimplementasikan PD). Driver klien sebelumnya mendaftarkan fungsi-fungsi tersebut dalam panggilannya ke UcmConnectorCreate.
Driver klien melakukan operasi pertukaran peran dengan menggunakan antarmuka perangkat keras.
EVT_UCM_CONNECTOR_SET_DATA_ROLE
Dalam implementasi panggilan balik, driver klien diharapkan untuk:
- Kirim pesan DR_Swap PD ke mitra port.
- Panggil UcmConnectorDataDirectionChanged untuk memberi tahu ekstensi kelas bahwa urutan pesan telah berhasil diselesaikan atau tidak berhasil.
EVT_UCM_CONNECTOR_SET_DATA_ROLE EvtSetDataRole; NTSTATUS EvtSetDataRole( UCMCONNECTOR Connector, UCM_TYPE_C_PORT_STATE DataRole ) { PCONNECTOR_CONTEXT connCtx; TRACE_INFO("EvtSetDataRole(%!UCM_TYPE_C_PORT_STATE!) Entry", DataRole); connCtx = GetConnectorContext(Connector); TRACE_FUNC_EXIT(); return STATUS_SUCCESS; }
EVT_UCM_CONNECTOR_SET_POWER_ROLE
Dalam implementasi panggilan balik, driver klien diharapkan untuk:
- Kirim pesan PR_Swap PD ke mitra port.
- Panggil UcmConnectorPowerDirectionChanged untuk memberi tahu ekstensi kelas bahwa urutan pesan telah berhasil diselesaikan atau tidak berhasil.
EVT_UCM_CONNECTOR_SET_POWER_ROLE EvtSetPowerRole; NTSTATUS EvtSetPowerRole( UCMCONNECTOR Connector, UCM_POWER_ROLE PowerRole ) { PCONNECTOR_CONTEXT connCtx; TRACE_INFO("EvtSetPowerRole(%!UCM_POWER_ROLE!) Entry", PowerRole); connCtx = GetConnectorContext(Connector); //PR_Swap operation. TRACE_FUNC_EXIT(); return STATUS_SUCCESS; }
Catatan
Driver klien dapat memanggil UcmConnectorDataDirectionChanged dan UcmConnectorPowerDirectionChanged secara asinkron, yang bukan dari utas panggilan balik. Dalam implementasi umum, ekstensi kelas memanggil fungsi panggilan balik yang menyebabkan driver klien memulai transaksi perangkat keras untuk mengirim pesan. Ketika transaksi selesai, perangkat keras akan memberi tahu driver. Driver memanggil metode tersebut untuk memberi tahu ekstensi kelas.
8. Laporkan peristiwa pencopotan konektor mitra
Driver klien harus memanggil UcmConnectorTypeCDetach ketika koneksi ke konektor mitra berakhir. Panggilan ini memberi tahu ekstensi kelas UCM, yang selanjutnya memberi tahu sistem operasi.
Contoh kasus penggunaan: Perangkat seluler yang terhubung ke PC
Saat perangkat yang menjalankan Windows 10 Mobile terhubung ke PC yang berjalan Windows 10 untuk edisi desktop melalui koneksi USB Type-C, sistem operasi memastikan bahwa perangkat seluler adalah Upstream Facing Port (UFP) karena MTP hanya berfungsi ke arah tersebut. Dalam skenario ini, berikut adalah urutan untuk koreksi peran data:
- Driver klien, yang berjalan di perangkat seluler, melaporkan peristiwa lampiran dengan memanggil UcmConnectorTypeCAttach dan melaporkan konektor mitra sebagai Port Menghadap Hilir (UFP).
- Driver klien melaporkan kontrak PD dengan memanggil UcmConnectorPdPartnerSourceCaps dan UcmConnectorPdConnectionStateChanged.
- Ekstensi kelas UCM memberi tahu driver sisi perangkat USB yang menyebabkan driver tersebut merespons enumerasi dari host. Informasi sistem operasi dipertukarkan melalui USB.
- Ekstensi kelas UCM UcmCx memanggil fungsi panggilan balik driver klien untuk mengubah peran: EVT_UCM_CONNECTOR_SET_DATA_ROLE dan EVT_UCM_CONNECTOR_SET_POWER_ROLE.
Catatan
Jika dua perangkat Windows 10 Mobile terhubung satu sama lain, pertukaran peran tidak dilakukan, dan pengguna diberi tahu bahwa koneksi tersebut bukan koneksi yang valid.