ट्रस्टी दो वर्गों के अनुप्रयोगों/सेवाओं को विकसित करने के लिए एपीआई प्रदान करता है:
- टीईई प्रोसेसर पर चलने वाले विश्वसनीय एप्लिकेशन या सेवाएं
- सामान्य/अविश्वसनीय अनुप्रयोग जो मुख्य प्रोसेसर पर चलते हैं और विश्वसनीय अनुप्रयोगों द्वारा प्रदान की जाने वाली सेवाओं का उपयोग करते हैं
ट्रस्टी एपीआई आम तौर पर गैर-सुरक्षित दुनिया के साथ संचार सहित ट्रस्टी इंटर-प्रोसेस कम्युनिकेशन (आईपीसी) सिस्टम का वर्णन करता है। मुख्य प्रोसेसर पर चलने वाला सॉफ़्टवेयर भरोसेमंद एप्लिकेशन/सेवाओं से कनेक्ट करने के लिए ट्रस्टी एपीआई का उपयोग कर सकता है और आईपी पर नेटवर्क सेवा की तरह उनके साथ मनमाने संदेशों का आदान-प्रदान कर सकता है। ऐप-स्तरीय प्रोटोकॉल का उपयोग करके इन संदेशों के डेटा प्रारूप और शब्दार्थ को निर्धारित करना एप्लिकेशन पर निर्भर है। संदेशों की विश्वसनीय डिलीवरी की गारंटी अंतर्निहित ट्रस्टी इन्फ्रास्ट्रक्चर (मुख्य प्रोसेसर पर चलने वाले ड्राइवरों के रूप में) द्वारा दी जाती है, और संचार पूरी तरह से अतुल्यकालिक है।
बंदरगाह और चैनल
पोर्ट का उपयोग ट्रस्टी एप्लिकेशन द्वारा सर्विस एंड-पॉइंट्स को नामित पथ के रूप में उजागर करने के लिए किया जाता है जिससे क्लाइंट कनेक्ट होते हैं। यह ग्राहकों को उपयोग करने के लिए एक सरल, स्ट्रिंग-आधारित सेवा आईडी देता है। नामकरण परंपरा रिवर्स-डीएनएस-शैली नामकरण है, उदाहरण के लिए com.google.servicename
।
जब कोई क्लाइंट किसी पोर्ट से जुड़ता है, तो क्लाइंट को सेवा के साथ इंटरैक्ट करने के लिए एक चैनल प्राप्त होता है। सेवा को आने वाले कनेक्शन को स्वीकार करना चाहिए, और जब ऐसा होता है, तो उसे भी एक चैनल प्राप्त होता है। संक्षेप में, पोर्ट का उपयोग सेवाओं को देखने के लिए किया जाता है और फिर संचार कनेक्टेड चैनलों की एक जोड़ी (यानी, पोर्ट पर कनेक्शन इंस्टेंस) पर होता है। जब कोई क्लाइंट किसी पोर्ट से जुड़ता है, तो एक सममित, द्वि-दिशात्मक कनेक्शन स्थापित होता है। इस पूर्ण-द्वैध पथ का उपयोग करते हुए, क्लाइंट और सर्वर मनमाने संदेशों का आदान-प्रदान कर सकते हैं, जब तक कि दोनों पक्ष कनेक्शन को फाड़ने का निर्णय नहीं लेते।
केवल सुरक्षित-पक्ष विश्वसनीय अनुप्रयोग या भरोसेमंद कर्नेल मॉड्यूल पोर्ट बना सकते हैं। गैर-सुरक्षित पक्ष (सामान्य दुनिया में) पर चलने वाले एप्लिकेशन केवल सुरक्षित पक्ष द्वारा प्रकाशित सेवाओं से जुड़ सकते हैं।
आवश्यकताओं के आधार पर, एक विश्वसनीय एप्लिकेशन एक ही समय में क्लाइंट और सर्वर दोनों हो सकता है। एक विश्वसनीय एप्लिकेशन जो एक सेवा (सर्वर के रूप में) प्रकाशित करता है उसे अन्य सेवाओं (क्लाइंट के रूप में) से कनेक्ट करने की आवश्यकता हो सकती है।
हैंडल एपीआई
हैंडल अहस्ताक्षरित पूर्णांक हैं जो UNIX में फ़ाइल डिस्क्रिप्टर के समान पोर्ट और चैनल जैसे संसाधनों का प्रतिनिधित्व करते हैं। हैंडल बनाए जाने के बाद, उन्हें एक एप्लिकेशन-विशिष्ट हैंडल टेबल में रखा जाता है और बाद में संदर्भित किया जा सकता है।
एक कॉलर set_cookie()
विधि का उपयोग करके निजी डेटा को एक हैंडल से जोड़ सकता है।
हैंडल एपीआई में तरीके
हैंडल केवल एक आवेदन के संदर्भ में मान्य हैं। जब तक स्पष्ट रूप से निर्दिष्ट नहीं किया जाता है, तब तक किसी एप्लिकेशन को अन्य एप्लिकेशन को हैंडल का मान पास नहीं करना चाहिए। एक हैंडल मान की व्याख्या केवल INVALID_IPC_HANDLE #define,
जिसे एक एप्लिकेशन एक संकेत के रूप में उपयोग कर सकता है कि एक हैंडल अमान्य या सेट नहीं है।
सेट_कुकी ()
कॉलर द्वारा प्रदत्त निजी डेटा को एक निर्दिष्ट हैंडल से संबद्ध करता है।
long set_cookie(uint32_t handle, void *cookie)
[में] handle
: एपीआई कॉल में से किसी एक द्वारा लौटाया गया कोई भी हैंडल
[इन] cookie
: भरोसेमंद एप्लिकेशन में मनमाने ढंग से उपयोगकर्ता-स्थान डेटा के लिए सूचक
[retval]: NO_ERROR
सफलता पर, < 0
त्रुटि कोड अन्यथा
यह कॉल घटनाओं को संभालने के लिए उपयोगी होती है जब वे हैंडल बनने के बाद बाद में होती हैं। इवेंट-हैंडलिंग मैकेनिज्म हैंडल और उसकी कुकी को इवेंट हैंडलर को वापस सप्लाई करता है।
wait()
कॉल का उपयोग करके घटनाओं के लिए हैंडल का इंतजार किया जा सकता है।
रुको()
निर्दिष्ट अवधि के लिए किसी दिए गए हैंडल पर किसी घटना के होने की प्रतीक्षा करता है।
long wait(uint32_t handle_id, uevent_t *event, unsigned long timeout_msecs)
[में] handle_id
: एपीआई कॉल में से किसी एक द्वारा लौटाया गया कोई भी हैंडल
[बाहर] event
: इस हैंडल पर हुई घटना का प्रतिनिधित्व करने वाली संरचना के लिए एक सूचक
[में] timeout_msecs
: मिलीसेकंड में एक टाइमआउट मान; -1 का मान एक अनंत समयबाह्य है
[retval]: NO_ERROR
यदि एक निर्दिष्ट समयबाह्य अंतराल के भीतर एक वैध घटना हुई; ERR_TIMED_OUT
यदि एक निर्दिष्ट समय समाप्त हो गया है लेकिन कोई घटना नहीं हुई है; < 0
अन्य त्रुटियों के लिए
सफल होने पर ( retval == NO_ERROR
), wait()
कॉल एक निर्दिष्ट uevent_t
संरचना को उस घटना के बारे में जानकारी से भर देता है जो हुई थी।
typedef struct uevent { uint32_t handle; /* handle this event is related to */ uint32_t event; /* combination of IPC_HANDLE_POLL_XXX flags */ void *cookie; /* cookie associated with this handle */ } uevent_t;
event
फ़ील्ड में निम्न मानों का संयोजन होता है:
enum { IPC_HANDLE_POLL_NONE = 0x0, IPC_HANDLE_POLL_READY = 0x1, IPC_HANDLE_POLL_ERROR = 0x2, IPC_HANDLE_POLL_HUP = 0x4, IPC_HANDLE_POLL_MSG = 0x8, IPC_HANDLE_POLL_SEND_UNBLOCKED = 0x10, … more values[TBD] };
IPC_HANDLE_POLL_NONE
- कोई भी घटना वास्तव में लंबित नहीं है, कॉलर को प्रतीक्षा को फिर से शुरू करना चाहिए
IPC_HANDLE_POLL_ERROR
- एक अनिर्दिष्ट आंतरिक त्रुटि हुई है
IPC_HANDLE_POLL_READY
- हैंडल के प्रकार पर निर्भर करता है, जो इस प्रकार है:
- बंदरगाहों के लिए, यह मान इंगित करता है कि एक लंबित कनेक्शन है
- चैनलों के लिए, यह मान इंगित करता है कि एक अतुल्यकालिक कनेक्शन (
connect()
देखें) स्थापित किया गया था
निम्नलिखित इवेंट केवल चैनलों के लिए प्रासंगिक हैं:
-
IPC_HANDLE_POLL_HUP
- इंगित करता है कि एक चैनल एक सहकर्मी द्वारा बंद कर दिया गया है -
IPC_HANDLE_POLL_MSG
- इंगित करता है कि इस चैनल के लिए एक संदेश लंबित है -
IPC_HANDLE_POLL_SEND_UNBLOCKED
- इंगित करता है कि पहले भेजा गया अवरुद्ध कॉलर फिर से संदेश भेजने का प्रयास कर सकता है (विवरण के लिएsend_msg()
का विवरण देखें)
निर्दिष्ट घटनाओं के संयोजन को संभालने के लिए एक ईवेंट हैंडलर तैयार किया जाना चाहिए, क्योंकि एक ही समय में कई बिट सेट किए जा सकते हैं। उदाहरण के लिए, एक चैनल के लिए, लंबित संदेशों का होना संभव है, और एक ही समय में एक सहकर्मी द्वारा बंद किया गया कनेक्शन।
ज्यादातर घटनाएं चिपचिपी होती हैं। वे तब तक बने रहते हैं जब तक अंतर्निहित स्थिति बनी रहती है (उदाहरण के लिए सभी लंबित संदेश प्राप्त होते हैं और लंबित कनेक्शन अनुरोधों को संभाला जाता है)। अपवाद IPC_HANDLE_POLL_SEND_UNBLOCKED
ईवेंट का मामला है, जिसे पढ़ने पर साफ़ कर दिया जाता है और एप्लिकेशन के पास इसे संभालने का केवल एक मौका होता है।
close()
विधि को कॉल करके हैंडल को नष्ट किया जा सकता है।
बंद करना()
निर्दिष्ट हैंडल से जुड़े संसाधन को नष्ट कर देता है और इसे हैंडल टेबल से हटा देता है।
long close(uint32_t handle_id);
[में] handle_id
: नष्ट करने के लिए हैंडल
[retval]: 0 अगर सफलता; एक नकारात्मक त्रुटि अन्यथा
सर्वर एपीआई
एक सर्वर एक या एक से अधिक नामित पोर्ट बनाकर शुरू करता है जो उसकी सेवा के अंत-बिंदुओं का प्रतिनिधित्व करता है। प्रत्येक पोर्ट को एक हैंडल द्वारा दर्शाया जाता है।
सर्वर एपीआई में तरीके
पोर्ट_क्रिएट ()
एक नामित सर्विस पोर्ट बनाता है।
long port_create (const char *path, uint num_recv_bufs, size_t recv_buf_size, uint32_t flags)
[में] path
: पोर्ट का स्ट्रिंग नाम (जैसा कि ऊपर वर्णित है)। यह नाम पूरे सिस्टम में अद्वितीय होना चाहिए; डुप्लिकेट बनाने का प्रयास विफल हो जाएगा।
[में] num_recv_bufs
: इस पोर्ट पर एक चैनल क्लाइंट के साथ डेटा के आदान-प्रदान की सुविधा के लिए बफ़र्स की अधिकतम संख्या पूर्व-आवंटित कर सकता है। दोनों दिशाओं में जाने वाले डेटा के लिए बफ़र्स की अलग-अलग गणना की जाती है, इसलिए यहां 1 निर्दिष्ट करने का अर्थ होगा 1 भेजें और 1 प्राप्त बफ़र को पूर्व-आवंटित किया जाता है। सामान्य तौर पर, आवश्यक बफ़र्स की संख्या क्लाइंट और सर्वर के बीच उच्च-स्तरीय प्रोटोकॉल समझौते पर निर्भर करती है। बहुत सिंक्रोनस प्रोटोकॉल के मामले में संख्या 1 जितनी कम हो सकती है (संदेश भेजें, दूसरा भेजने से पहले उत्तर प्राप्त करें)। लेकिन संख्या अधिक हो सकती है यदि ग्राहक उत्तर के प्रकट होने से पहले एक से अधिक संदेश भेजने की अपेक्षा करता है (उदाहरण के लिए, एक संदेश प्रस्तावना के रूप में और दूसरा वास्तविक आदेश के रूप में)। आवंटित बफर सेट प्रति चैनल हैं, इसलिए दो अलग-अलग कनेक्शन (चैनल) में अलग-अलग बफर सेट होंगे।
[में] recv_buf_size
: उपरोक्त बफर सेट में प्रत्येक व्यक्तिगत बफर का अधिकतम आकार। यह मान प्रोटोकॉल पर निर्भर है और सहकर्मी के साथ आपके द्वारा आदान-प्रदान किए जा सकने वाले अधिकतम संदेश आकार को प्रभावी ढंग से सीमित करता है
[में] flags
: झंडे का एक संयोजन जो अतिरिक्त पोर्ट व्यवहार को निर्दिष्ट करता है
यह मान निम्न मानों का संयोजन होना चाहिए:
IPC_PORT_ALLOW_TA_CONNECT
- अन्य सुरक्षित ऐप्स से कनेक्शन की अनुमति देता है
IPC_PORT_ALLOW_NS_CONNECT
- गैर-सुरक्षित दुनिया से कनेक्शन की अनुमति देता है
[retval]: गैर-नकारात्मक होने पर बनाए गए पोर्ट को हैंडल करें या नकारात्मक होने पर विशिष्ट त्रुटि करें
सर्वर तब wait()
कॉल का उपयोग करके आने वाले कनेक्शन के लिए पोर्ट हैंडल की सूची का चुनाव करता है। uevent_t
संरचना के event
फ़ील्ड में IPC_HANDLE_POLL_READY
बिट सेट द्वारा इंगित कनेक्शन अनुरोध प्राप्त करने पर, सर्वर को कनेक्शन स्थापित करने के लिए accept()
को कॉल करना चाहिए और एक चैनल बनाना चाहिए (दूसरे हैंडल द्वारा दर्शाया गया) जिसे बाद में आने वाले संदेशों के लिए चुना जा सकता है। .
मानना()
आने वाले कनेक्शन को स्वीकार करता है और एक चैनल को एक हैंडल प्राप्त करता है।
long accept(uint32_t handle_id, uuid_t *peer_uuid);
[में] handle_id
: उस पोर्ट का प्रतिनिधित्व करने वाला हैंडल जिससे क्लाइंट जुड़ा है
[आउट] peer_uuid
: कनेक्टिंग क्लाइंट एप्लिकेशन के यूयूआईडी से भरे जाने के लिए uuud_t
संरचना का सूचक। यदि कनेक्शन गैर-सुरक्षित दुनिया से उत्पन्न होता है तो यह सभी शून्य पर सेट हो जाएगा
[retval]: एक चैनल को हैंडल करें (यदि गैर-नकारात्मक) जिस पर सर्वर क्लाइंट के साथ संदेशों का आदान-प्रदान कर सकता है (या अन्यथा एक त्रुटि कोड)
क्लाइंट एपीआई
इस खंड में क्लाइंट एपीआई में विधियां हैं।
क्लाइंट एपीआई में तरीके
जुडिये()
नाम से निर्दिष्ट पोर्ट से कनेक्शन आरंभ करता है।
long connect(const char *path, uint flags);
[इन] path
: एक भरोसेमंद एप्लिकेशन द्वारा प्रकाशित पोर्ट का नाम
[में] flags
: अतिरिक्त, वैकल्पिक व्यवहार निर्दिष्ट करता है
[retval]: एक चैनल को हैंडल करें जिस पर सर्वर के साथ संदेशों का आदान-प्रदान किया जा सकता है; त्रुटि अगर नकारात्मक
यदि कोई flags
निर्दिष्ट नहीं है ( flags
पैरामीटर 0 पर सेट है), कॉल connect()
एक निर्दिष्ट पोर्ट के लिए एक सिंक्रोनस कनेक्शन शुरू करता है जो पोर्ट मौजूद नहीं होने पर तुरंत एक त्रुटि देता है, और एक ब्लॉक बनाता है जब तक कि सर्वर अन्यथा एक कनेक्शन स्वीकार नहीं करता है .
नीचे वर्णित दो मानों के संयोजन को निर्दिष्ट करके इस व्यवहार को बदला जा सकता है:
enum { IPC_CONNECT_WAIT_FOR_PORT = 0x1, IPC_CONNECT_ASYNC = 0x2, };
IPC_CONNECT_WAIT_FOR_PORT
- एक connect()
कॉल को प्रतीक्षा करने के लिए मजबूर करता है यदि निर्दिष्ट पोर्ट तुरंत निष्पादन में मौजूद नहीं है, बजाय तुरंत विफल होने के।
IPC_CONNECT_ASYNC
- यदि सेट किया गया है, तो एक अतुल्यकालिक कनेक्शन शुरू करता है। सामान्य ऑपरेशन शुरू करने से पहले uevent_t
संरचना के ईवेंट फ़ील्ड में IPC_HANDLE_POLL_READY
बिट सेट द्वारा इंगित कनेक्शन पूर्ण होने की घटना के लिए एक एप्लिकेशन को लौटाए गए हैंडल के लिए मतदान wait()
होता है।
मैसेजिंग एपीआई
मैसेजिंग एपीआई कॉल पहले से स्थापित कनेक्शन (चैनल) पर संदेशों को भेजने और पढ़ने में सक्षम बनाता है। मैसेजिंग एपीआई कॉल सर्वर और क्लाइंट के लिए समान हैं।
क्लाइंट connect()
कॉल जारी करके चैनल का हैंडल प्राप्त करता है, और सर्वर को ऊपर वर्णित accept()
कॉल से चैनल हैंडल प्राप्त होता है।
एक भरोसेमंद संदेश की संरचना
जैसा कि निम्नलिखित में दिखाया गया है, ट्रस्टी एपीआई द्वारा आदान-प्रदान किए गए संदेशों में एक न्यूनतम संरचना होती है, जो सर्वर और क्लाइंट को वास्तविक सामग्री के शब्दार्थ पर सहमत होने के लिए छोड़ देती है:
/* * IPC message */ typedef struct iovec { void *base; size_t len; } iovec_t; typedef struct ipc_msg { uint num_iov; /* number of iovs in this message */ iovec_t *iov; /* pointer to iov array */ uint num_handles; /* reserved, currently not supported */ handle_t *handles; /* reserved, currently not supported */ } ipc_msg_t;
एक संदेश iovec_t
संरचनाओं की एक सरणी द्वारा दर्शाए गए एक या अधिक गैर-सन्निहित बफ़र्स से बना हो सकता है। ट्रस्टी iov
सरणी का उपयोग करके इन ब्लॉकों को स्कैटर-इकट्ठा पढ़ता और लिखता है। बफ़र्स की सामग्री जिसे iov
सरणी द्वारा वर्णित किया जा सकता है, पूरी तरह से मनमाना है।
मैसेजिंग एपीआई में तरीके
send_msg ()
एक निर्दिष्ट चैनल पर एक संदेश भेजता है।
long send_msg(uint32_t handle, ipc_msg_t *msg);
[में] handle
: उस चैनल को हैंडल करें जिस पर संदेश भेजना है
[में] संदेश: संदेश का वर्णन करने वाले msg
ipc_msg_t structure
के लिए सूचक
[retval]: सफलता पर भेजे गए बाइट्स की कुल संख्या; एक नकारात्मक त्रुटि अन्यथा
यदि क्लाइंट (या सर्वर) चैनल पर संदेश भेजने की कोशिश कर रहा है और गंतव्य सहकर्मी संदेश कतार में कोई स्थान नहीं है, तो चैनल एक भेजने-अवरुद्ध स्थिति में प्रवेश कर सकता है (यह एक साधारण सिंक्रोनस अनुरोध/उत्तर प्रोटोकॉल के लिए कभी नहीं होना चाहिए) लेकिन अधिक जटिल मामलों में हो सकता है) जो एक ERR_NOT_ENOUGH_BUFFER
त्रुटि कोड लौटाकर इंगित किया गया है। ऐसे मामले में, कॉल करने वाले को तब तक प्रतीक्षा करनी चाहिए जब तक कि पीयर अपनी प्राप्त कतार में कुछ स्थान खाली नहीं कर देता, हैंडलिंग और रिटायरिंग संदेशों को पुनः प्राप्त करके, IPC_HANDLE_POLL_SEND_UNBLOCKED
बिट सेट द्वारा uevent_t
संरचना के event
फ़ील्ड में wait()
कॉल द्वारा लौटाया जाता है।
get_msg ()
आने वाले संदेश कतार में अगले संदेश के बारे में मेटा-सूचना प्राप्त करता है
एक निर्दिष्ट चैनल की।
long get_msg(uint32_t handle, ipc_msg_info_t *msg_info);
[में] handle
: चैनल का हैंडल जिस पर एक नया संदेश प्राप्त किया जाना चाहिए
[बाहर] msg_info
: संदेश सूचना संरचना इस प्रकार वर्णित है:
typedef struct ipc_msg_info { size_t len; /* total message length */ uint32_t id; /* message id */ } ipc_msg_info_t;
प्रत्येक संदेश को बकाया संदेशों के सेट में एक अद्वितीय आईडी दी जाती है, और प्रत्येक संदेश की कुल लंबाई भर दी जाती है। यदि प्रोटोकॉल द्वारा कॉन्फ़िगर और अनुमति दी जाती है, तो किसी विशेष चैनल के लिए एक साथ कई बकाया (खोले) संदेश हो सकते हैं।
[retval]: NO_ERROR
सफलता पर; एक नकारात्मक त्रुटि अन्यथा
read_msg ()
निर्दिष्ट ऑफसेट से शुरू होने वाली निर्दिष्ट आईडी के साथ संदेश की सामग्री को पढ़ता है।
long read_msg(uint32_t handle, uint32_t msg_id, uint32_t offset, ipc_msg_t *msg);
[in] handle
: उस चैनल का हैंडल जिससे संदेश पढ़ना है
[में] msg_id
: पढ़ने के लिए संदेश की आईडी
[इन] offset
: उस संदेश में ऑफ़सेट करें जिससे पढ़ना शुरू करना है
[in] msg
: ipc_msg_t
संरचना की ओर संकेत करता है जो बफ़र्स के एक सेट का वर्णन करता है जिसमें आने वाले संदेश डेटा को संग्रहीत करना है
[retval]: सफलता पर dst
बफ़र्स में संग्रहीत बाइट्स की कुल संख्या; एक नकारात्मक त्रुटि अन्यथा
read_msg
विधि को आवश्यकतानुसार अलग-अलग (जरूरी नहीं कि अनुक्रमिक) ऑफसेट से शुरू करके कई बार कहा जा सकता है।
put_msg ()
एक निर्दिष्ट आईडी के साथ एक संदेश सेवानिवृत्त करता है।
long put_msg(uint32_t handle, uint32_t msg_id);
[in] handle
: उस चैनल का हैंडल जिस पर मैसेज आया है
[में] msg_id
: संदेश के सेवानिवृत्त होने की आईडी
[retval]: NO_ERROR
सफलता पर; एक नकारात्मक त्रुटि अन्यथा
संदेश के सेवानिवृत्त होने के बाद संदेश सामग्री तक नहीं पहुंचा जा सकता है और इसके कब्जे वाले बफर को मुक्त कर दिया गया है।
फाइल डिस्क्रिप्टर एपीआई
फाइल डिस्क्रिप्टर एपीआई में read()
, write()
और ioctl()
कॉल शामिल हैं। ये सभी कॉल फाइल डिस्क्रिप्टर के एक पूर्वनिर्धारित (स्थिर) सेट पर काम कर सकते हैं जो परंपरागत रूप से छोटी संख्याओं द्वारा दर्शाए जाते हैं। वर्तमान कार्यान्वयन में, फ़ाइल डिस्क्रिप्टर स्पेस आईपीसी हैंडल स्पेस से अलग है। ट्रस्टी में फाइल डिस्क्रिप्टर एपीआई एक पारंपरिक फाइल डिस्क्रिप्टर-आधारित एपीआई के समान है।
डिफ़ॉल्ट रूप से, 3 पूर्वनिर्धारित (मानक और प्रसिद्ध) फ़ाइल डिस्क्रिप्टर हैं:
- 0 - मानक इनपुट। मानक इनपुट
fd
का डिफ़ॉल्ट कार्यान्वयन एक नो-ऑप है (क्योंकि विश्वसनीय अनुप्रयोगों में एक इंटरैक्टिव कंसोल होने की उम्मीद नहीं है) इसलिएfd
0 परioctl()
को पढ़ना, लिखना या आह्वान करना एकERR_NOT_SUPPORTED
त्रुटि लौटाना चाहिए। - 1 - मानक आउटपुट। मानक आउटपुट के लिए लिखे गए डेटा को यूएआरटी और/या गैर-सुरक्षित पक्ष पर उपलब्ध मेमोरी लॉग, प्लेटफॉर्म और कॉन्फ़िगरेशन के आधार पर (एलके डीबग स्तर के आधार पर) रूट किया जा सकता है। गैर-महत्वपूर्ण डीबग लॉग और संदेश मानक आउटपुट में जाने चाहिए।
read()
औरioctl()
विधियाँ नो-ऑप्स हैं और उन्हें एकERR_NOT_SUPPORTED
त्रुटि वापस करनी चाहिए। - 2 - मानक त्रुटि। मानक त्रुटि के लिए लिखा गया डेटा प्लेटफॉर्म और कॉन्फ़िगरेशन के आधार पर गैर-सुरक्षित पक्ष पर उपलब्ध यूएआरटी या मेमोरी लॉग को रूट किया जाना चाहिए। मानक त्रुटि के लिए केवल महत्वपूर्ण संदेश लिखने की अनुशंसा की जाती है, क्योंकि इस धारा के अनियंत्रित होने की बहुत संभावना है।
read()
औरioctl()
विधियाँ नो-ऑप्स हैं और उन्हें एकERR_NOT_SUPPORTED
त्रुटि वापस करनी चाहिए।
भले ही फ़ाइल डिस्क्रिप्टर के इस सेट को अधिक fds
लागू करने के लिए बढ़ाया जा सकता है (प्लेटफ़ॉर्म-विशिष्ट एक्सटेंशन को लागू करने के लिए), फ़ाइल डिस्क्रिप्टर का विस्तार सावधानी के साथ किया जाना चाहिए। फ़ाइल डिस्क्रिप्टर का विस्तार करने से विरोध पैदा हो सकता है और आमतौर पर इसकी अनुशंसा नहीं की जाती है।
फाइल डिस्क्रिप्टर एपीआई में तरीके
पढ़ना()
निर्दिष्ट फ़ाइल डिस्क्रिप्टर से डेटा के बाइट्स count
के लिए पढ़ने का प्रयास।
long read(uint32_t fd, void *buf, uint32_t count);
[in] fd
: फाइल डिस्क्रिप्टर जिससे पढ़ना है
[बाहर] buf
: एक बफर को पॉइंटर जिसमें डेटा स्टोर करना है
[में] count
: पढ़ने के लिए बाइट्स की अधिकतम संख्या
[retval]: बाइट्स की लौटाई गई संख्या पढ़ी गई; एक नकारात्मक त्रुटि अन्यथा
लिखना()
निर्दिष्ट फ़ाइल डिस्क्रिप्टर को डेटा के बाइट्स count
के लिए लिखता है।
long write(uint32_t fd, void *buf, uint32_t count);
[in] fd
: फाइल डिस्क्रिप्टर जिसमें लिखना है
[बाहर] buf
: लिखने के लिए डेटा का सूचक
[में] count
: लिखने के लिए बाइट्स की अधिकतम संख्या
[retval]: लिखित बाइट्स की लौटाई गई संख्या; एक नकारात्मक त्रुटि अन्यथा
आईओसीटीएल ()
किसी दिए गए फ़ाइल डिस्क्रिप्टर के लिए एक निर्दिष्ट ioctl
कमांड को आमंत्रित करता है।
long ioctl(uint32_t fd, uint32_t cmd, void *args);
[in] fd
: फाइल डिस्क्रिप्टर जिस पर ioctl()
को इनवाइट करना है
[in] cmd
: ioctl
कमांड
[इन/आउट] args
: ioctl()
तर्कों के लिए सूचक
विविध एपीआई
विविध एपीआई में तरीके
समय निकालो()
वर्तमान सिस्टम समय (नैनोसेकंड में) देता है।
long gettime(uint32_t clock_id, uint32_t flags, uint64_t *time);
[में] clock_id
: प्लेटफॉर्म पर निर्भर; डिफ़ॉल्ट के लिए शून्य पास करें
[में] flags
: सुरक्षित, शून्य होना चाहिए
[में] time
: एक int64_t
मान का सूचक जिससे वर्तमान समय संग्रहीत किया जा सके
[retval]: NO_ERROR
सफलता पर; एक नकारात्मक त्रुटि अन्यथा
नैनोस्लीप ()
निर्दिष्ट अवधि के लिए कॉलिंग एप्लिकेशन के निष्पादन को निलंबित करता है और उस अवधि के बाद इसे फिर से शुरू करता है।
long nanosleep(uint32_t clock_id, uint32_t flags, uint64_t sleep_time)
[में] clock_id
: आरक्षित, शून्य होना चाहिए
[में] flags
: सुरक्षित, शून्य होना चाहिए
[में] sleep_time
: नैनोसेकंड में सोने का समय
[retval]: NO_ERROR
सफलता पर; एक नकारात्मक त्रुटि अन्यथा
एक विश्वसनीय एप्लिकेशन सर्वर का उदाहरण
निम्नलिखित नमूना आवेदन उपरोक्त एपीआई के उपयोग को दर्शाता है। नमूना एक "इको" सेवा बनाता है जो कई आने वाले कनेक्शनों को संभालता है और कॉलर को वापस उन सभी संदेशों को प्रतिबिंबित करता है जो इसे ग्राहकों से प्राप्त होते हैं जो सुरक्षित या गैर-सुरक्षित पक्ष से उत्पन्न होते हैं।
#include <uapi/err.h> #include <stdbool.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <trusty_ipc.h> #define LOG_TAG "echo_srv" #define TLOGE(fmt, ...) \ fprintf(stderr, "%s: %d: " fmt, LOG_TAG, __LINE__, ##__VA_ARGS__) # define MAX_ECHO_MSG_SIZE 64 static const char * srv_name = "com.android.echo.srv.echo"; static uint8_t msg_buf[MAX_ECHO_MSG_SIZE]; /* * Message handler */ static int handle_msg(handle_t chan) { int rc; struct iovec iov; ipc_msg_t msg; ipc_msg_info_t msg_inf; iov.iov_base = msg_buf; iov.iov_len = sizeof(msg_buf); msg.num_iov = 1; msg.iov = &iov; msg.num_handles = 0; msg.handles = NULL; /* get message info */ rc = get_msg(chan, &msg_inf); if (rc == ERR_NO_MSG) return NO_ERROR; /* no new messages */ if (rc != NO_ERROR) { TLOGE("failed (%d) to get_msg for chan (%d)\n", rc, chan); return rc; } /* read msg content */ rc = read_msg(chan, msg_inf.id, 0, &msg); if (rc < 0) { TLOGE("failed (%d) to read_msg for chan (%d)\n", rc, chan); return rc; } /* update number of bytes received */ iov.iov_len = (size_t) rc; /* send message back to the caller */ rc = send_msg(chan, &msg); if (rc < 0) { TLOGE("failed (%d) to send_msg for chan (%d)\n", rc, chan); return rc; } /* retire message */ rc = put_msg(chan, msg_inf.id); if (rc != NO_ERROR) { TLOGE("failed (%d) to put_msg for chan (%d)\n", rc, chan); return rc; } return NO_ERROR; } /* * Channel event handler */ static void handle_channel_event(const uevent_t * ev) { int rc; if (ev->event & IPC_HANDLE_POLL_MSG) { rc = handle_msg(ev->handle); if (rc != NO_ERROR) { /* report an error and close channel */ TLOGE("failed (%d) to handle event on channel %d\n", rc, ev->handle); close(ev->handle); } return; } if (ev->event & IPC_HANDLE_POLL_HUP) { /* closed by peer. */ close(ev->handle); return; } } /* * Port event handler */ static void handle_port_event(const uevent_t * ev) { uuid_t peer_uuid; if ((ev->event & IPC_HANDLE_POLL_ERROR) || (ev->event & IPC_HANDLE_POLL_HUP) || (ev->event & IPC_HANDLE_POLL_MSG) || (ev->event & IPC_HANDLE_POLL_SEND_UNBLOCKED)) { /* should never happen with port handles */ TLOGE("error event (0x%x) for port (%d)\n", ev->event, ev->handle); abort(); } if (ev->event & IPC_HANDLE_POLL_READY) { /* incoming connection: accept it */ int rc = accept(ev->handle, &peer_uuid); if (rc < 0) { TLOGE("failed (%d) to accept on port %d\n", rc, ev->handle); return; } handle_t chan = rc; while (true){ struct uevent cev; rc = wait(chan, &cev, INFINITE_TIME); if (rc < 0) { TLOGE("wait returned (%d)\n", rc); abort(); } handle_channel_event(&cev); if (cev.event & IPC_HANDLE_POLL_HUP) { return; } } } } /* * Main application entry point */ int main(void) { int rc; handle_t port; /* Initialize service */ rc = port_create(srv_name, 1, MAX_ECHO_MSG_SIZE, IPC_PORT_ALLOW_NS_CONNECT | IPC_PORT_ALLOW_TA_CONNECT); if (rc < 0) { TLOGE("Failed (%d) to create port %s\n", rc, srv_name); abort(); } port = (handle_t) rc; /* enter main event loop */ while (true) { uevent_t ev; ev.handle = INVALID_IPC_HANDLE; ev.event = 0; ev.cookie = NULL; /* wait forever */ rc = wait(port, &ev, INFINITE_TIME); if (rc == NO_ERROR) { /* got an event */ handle_port_event(&ev); } else { TLOGE("wait returned (%d)\n", rc); abort(); } } return 0; }
run_end_to_end_msg_test()
विधि "इको" सेवा को अतुल्यकालिक रूप से 10,000 संदेश भेजती है और उत्तरों को संभालती है।
static int run_echo_test(void) { int rc; handle_t chan; uevent_t uevt; uint8_t tx_buf[64]; uint8_t rx_buf[64]; ipc_msg_info_t inf; ipc_msg_t tx_msg; iovec_t tx_iov; ipc_msg_t rx_msg; iovec_t rx_iov; /* prepare tx message buffer */ tx_iov.base = tx_buf; tx_iov.len = sizeof(tx_buf); tx_msg.num_iov = 1; tx_msg.iov = &tx_iov; tx_msg.num_handles = 0; tx_msg.handles = NULL; memset (tx_buf, 0x55, sizeof(tx_buf)); /* prepare rx message buffer */ rx_iov.base = rx_buf; rx_iov.len = sizeof(rx_buf); rx_msg.num_iov = 1; rx_msg.iov = &rx_iov; rx_msg.num_handles = 0; rx_msg.handles = NULL; /* open connection to echo service */ rc = sync_connect(srv_name, 1000); if(rc < 0) return rc; /* got channel */ chan = (handle_t)rc; /* send/receive 10000 messages asynchronously. */ uint tx_cnt = 10000; uint rx_cnt = 10000; while (tx_cnt || rx_cnt) { /* send messages until all buffers are full */ while (tx_cnt) { rc = send_msg(chan, &tx_msg); if (rc == ERR_NOT_ENOUGH_BUFFER) break; /* no more space */ if (rc != 64) { if (rc > 0) { /* incomplete send */ rc = ERR_NOT_VALID; } goto abort_test; } tx_cnt--; } /* wait for reply msg or room */ rc = wait(chan, &uevt, 1000); if (rc != NO_ERROR) goto abort_test; /* drain all messages */ while (rx_cnt) { /* get a reply */ rc = get_msg(chan, &inf); if (rc == ERR_NO_MSG) break; /* no more messages */ if (rc != NO_ERROR) goto abort_test; /* read reply data */ rc = read_msg(chan, inf.id, 0, &rx_msg); if (rc != 64) { /* unexpected reply length */ rc = ERR_NOT_VALID; goto abort_test; } /* discard reply */ rc = put_msg(chan, inf.id); if (rc != NO_ERROR) goto abort_test; rx_cnt--; } } abort_test: close(chan); return rc; }
गैर-सुरक्षित विश्व एपीआई और एप्लिकेशन
भरोसेमंद सेवाओं का एक सेट, सुरक्षित पक्ष से प्रकाशित और IPC_PORT_ALLOW_NS_CONNECT
विशेषता के साथ चिह्नित, गैर-सुरक्षित पक्ष पर चल रहे कर्नेल और उपयोगकर्ता अंतरिक्ष कार्यक्रमों के लिए सुलभ हैं।
गैर-सुरक्षित पक्ष (कर्नेल और उपयोगकर्ता स्थान) पर निष्पादन वातावरण सुरक्षित पक्ष पर निष्पादन वातावरण से काफी अलग है। इसलिए, दोनों वातावरणों के लिए एक पुस्तकालय के बजाय, एपीआई के दो अलग-अलग सेट हैं। कर्नेल में, क्लाइंट एपीआई ट्रस्टी-आईपीसी कर्नेल ड्राइवर द्वारा प्रदान किया जाता है और एक कैरेक्टर डिवाइस नोड को पंजीकृत करता है जिसका उपयोग उपयोगकर्ता अंतरिक्ष प्रक्रियाओं द्वारा सुरक्षित पक्ष पर चल रही सेवाओं के साथ संचार करने के लिए किया जा सकता है।
उपयोगकर्ता स्थान भरोसेमंद आईपीसी क्लाइंट एपीआई
यूजर स्पेस ट्रस्टी आईपीसी क्लाइंट एपीआई लाइब्रेरी डिवाइस नोड fd
के ऊपर एक पतली परत है।
एक यूजर स्पेस प्रोग्राम एक निर्दिष्ट ट्रस्टी सर्विस से कनेक्शन को इनिशियलाइज़ करते हुए, tipc_connect()
को कॉल करके एक संचार सत्र शुरू करता है। आंतरिक रूप से, tipc_connect()
कॉल एक फ़ाइल डिस्क्रिप्टर प्राप्त करने के लिए एक निर्दिष्ट डिवाइस नोड खोलता है और एक TIPC_IOC_CONNECT ioctl()
कॉल को argp
पैरामीटर के साथ एक स्ट्रिंग की ओर इशारा करता है जिसमें एक सेवा नाम होता है जिससे कनेक्ट होना है।
#define TIPC_IOC_MAGIC 'r' #define TIPC_IOC_CONNECT _IOW(TIPC_IOC_MAGIC, 0x80, char *)
परिणामी फ़ाइल डिस्क्रिप्टर का उपयोग केवल उस सेवा के साथ संचार करने के लिए किया जा सकता है जिसके लिए इसे बनाया गया था। जब कनेक्शन की आवश्यकता नहीं है, तो tipc_close()
को कॉल करके फ़ाइल डिस्क्रिप्टर को बंद कर दिया जाना चाहिए।
tipc_connect()
कॉल द्वारा प्राप्त फ़ाइल डिस्क्रिप्टर एक विशिष्ट वर्ण डिवाइस नोड के रूप में व्यवहार करता है; फ़ाइल विवरणक:
- यदि आवश्यक हो तो गैर-अवरुद्ध मोड में स्विच किया जा सकता है
- दूसरी तरफ संदेश भेजने के लिए एक मानक
write()
कॉल का उपयोग करने के लिए लिखा जा सकता है - नियमित फ़ाइल डिस्क्रिप्टर के रूप में आने वाले संदेशों की उपलब्धता के लिए मतदान किया जा सकता है (
poll()
कॉल याselect()
कॉल का उपयोग करके) - आने वाले संदेशों को पुनः प्राप्त करने के लिए पढ़ा जा सकता है
एक कॉलर निर्दिष्ट fd
के लिए एक लिखित कॉल निष्पादित करके ट्रस्टी सेवा को एक संदेश भेजता है। उपरोक्त write()
कॉल को दिए गए सभी डेटा को ट्रस्टी-आईपीसी ड्राइवर द्वारा एक संदेश में बदल दिया जाता है। संदेश को सुरक्षित पक्ष में वितरित किया जाता है जहां डेटा को ट्रस्टी कर्नेल में आईपीसी सबसिस्टम द्वारा नियंत्रित किया जाता है और उचित गंतव्य पर रूट किया जाता है और एक विशेष चैनल हैंडल पर IPC_HANDLE_POLL_MSG
ईवेंट के रूप में ऐप इवेंट लूप में वितरित किया जाता है। विशेष, सेवा-विशिष्ट प्रोटोकॉल के आधार पर, ट्रस्टी सेवा एक या एक से अधिक उत्तर संदेश भेज सकती है जो गैर-सुरक्षित पक्ष में वापस वितरित किए जाते हैं और उपयुक्त चैनल फ़ाइल डिस्क्रिप्टर संदेश कतार में रखे जाते हैं जिन्हें उपयोगकर्ता अंतरिक्ष एप्लिकेशन द्वारा पुनर्प्राप्त किया जाता read()
। read()
कॉल करें।
टिपक_कनेक्ट ()
एक निर्दिष्ट tipc
डिवाइस नोड खोलता है और एक निर्दिष्ट ट्रस्टी सेवा से कनेक्शन शुरू करता है।
int tipc_connect(const char *dev_name, const char *srv_name);
[में] dev_name
: भरोसेमंद आईपीसी डिवाइस नोड खोलने के लिए पथ
[में] srv_name
: एक प्रकाशित भरोसेमंद सेवा का नाम जिससे जुड़ना है
[retval]: सफलता पर मान्य फ़ाइल डिस्क्रिप्टर, -1 अन्यथा।
टिपक_क्लोज़ ()
फ़ाइल डिस्क्रिप्टर द्वारा निर्दिष्ट ट्रस्टी सेवा से कनेक्शन बंद कर देता है।
int tipc_close(int fd);
[in] fd
: फ़ाइल डिस्क्रिप्टर जिसे पहले एक tipc_connect()
कॉल द्वारा खोला गया था
कर्नेल भरोसेमंद आईपीसी क्लाइंट एपीआई
कर्नेल ट्रस्टी आईपीसी क्लाइंट एपीआई कर्नेल ड्राइवरों के लिए उपलब्ध है। यूजर स्पेस ट्रस्टी आईपीसी एपीआई इस एपीआई के शीर्ष पर लागू किया गया है।
सामान्य तौर पर, इस एपीआई के विशिष्ट उपयोग में एक कॉलर होता है जो tipc_create_channel()
फ़ंक्शन का उपयोग करके एक struct tipc_chan
ऑब्जेक्ट बनाता है और फिर सुरक्षित पक्ष पर चल रही भरोसेमंद आईपीसी सेवा से कनेक्शन शुरू करने के लिए tipc_chan_connect()
कॉल का उपयोग करता है। संसाधनों को साफ करने के लिए टिपक_चन_शटडाउन tipc_chan_shutdown()
के बाद tipc_chan_destroy()
को कॉल करके रिमोट साइड से कनेक्शन समाप्त किया जा सकता है।
एक सूचना प्राप्त करने पर ( handle_event()
कॉलबैक के माध्यम से) कि एक कनेक्शन सफलतापूर्वक स्थापित हो गया है, एक कॉलर निम्नलिखित करता है:
-
tipc_chan_get_txbuf_timeout()
कॉल का उपयोग करके एक संदेश बफर प्राप्त करता है - एक संदेश लिखता है, और
- एक भरोसेमंद सेवा (सुरक्षित पक्ष पर) को डिलीवरी के लिए
tipc_chan_queue_msg()
विधि का उपयोग करके संदेश को कतारबद्ध करता है, जिससे चैनल जुड़ा हुआ है
कतार सफल होने के बाद, कॉलर को संदेश बफ़र को भूल जाना चाहिए क्योंकि संदेश बफ़र अंततः दूरस्थ पक्ष द्वारा संसाधित करने के बाद मुक्त बफर पूल में वापस आ जाता है (बाद में पुन: उपयोग के लिए, अन्य संदेशों के लिए)। उपयोगकर्ता को केवल tipc_chan_put_txbuf()
कॉल करने की आवश्यकता है यदि वह इस तरह के बफर को कतारबद्ध करने में विफल रहता है या अब इसकी आवश्यकता नहीं है।
एक एपीआई उपयोगकर्ता एक handle_msg()
अधिसूचना कॉलबैक (जिसे भरोसेमंद-आईपीसी rx
वर्कक्यू के संदर्भ में कहा जाता है) को संभालने के द्वारा रिमोट साइड से संदेश प्राप्त करता है जो एक rx
बफर को एक पॉइंटर प्रदान करता है जिसमें आने वाले संदेश को संभाला जाना है।
यह उम्मीद की जाती है कि handle_msg()
कॉलबैक कार्यान्वयन एक वैध struct tipc_msg_buf
पर एक पॉइंटर लौटाएगा। यह आने वाले संदेश बफर के समान हो सकता है यदि इसे स्थानीय रूप से नियंत्रित किया जाता है और अब इसकी आवश्यकता नहीं है। वैकल्पिक रूप से, यदि आने वाले बफ़र को आगे की प्रक्रिया के लिए कतारबद्ध किया जाता है, तो यह एक नया बफ़र हो सकता है जिसे एक tipc_chan_get_rxbuf()
कॉल द्वारा प्राप्त किया जाता है। एक अलग किए गए rx
बफ़र को ट्रैक किया जाना चाहिए और अंततः एक tipc_chan_put_rxbuf()
कॉल का उपयोग करके जारी किया जाना चाहिए जब इसकी आवश्यकता नहीं रह जाती है।
कर्नेल भरोसेमंद आईपीसी क्लाइंट एपीआई में तरीके
टिपक_क्रिएट_चैनल ()
एक विशेष ट्रस्टी-आईपीसी डिवाइस के लिए एक भरोसेमंद आईपीसी चैनल का एक उदाहरण बनाता और कॉन्फ़िगर करता है।
struct tipc_chan *tipc_create_channel(struct device *dev, const struct tipc_chan_ops *ops, void *cb_arg);
[में] dev
: भरोसेमंद-आईपीसी के लिए सूचक जिसके लिए डिवाइस चैनल बनाया गया है
[इन] ops
: एक struct tipc_chan_ops
के लिए पॉइंटर, जिसमें कॉलर-विशिष्ट कॉलबैक भरे हुए हैं
[में] cb_arg
: डेटा का सूचक जो tipc_chan_ops
कॉलबैक को पास किया जाएगा
[रिटवल]: सफलता पर struct tipc_chan
के नव-निर्मित उदाहरण के लिए सूचक, अन्यथा ERR_PTR(err)
सामान्य तौर पर, एक कॉलर को दो कॉलबैक प्रदान करना चाहिए जो कि संबंधित गतिविधि होने पर एसिंक्रोनस रूप से लागू होते हैं।
चैनल स्थिति परिवर्तन के बारे में एक कॉलर को सूचित करने के लिए void (*handle_event)(void *cb_arg, int event)
ईवेंट को बुलाया जाता है।
[में] cb_arg
: एक tipc_create_channel()
कॉल को पास किए गए डेटा का सूचक
[में] event
: एक घटना जो निम्नलिखित मूल्यों में से एक हो सकती है:
-
TIPC_CHANNEL_CONNECTED
- रिमोट साइड से एक सफल कनेक्शन का संकेत देता है -
TIPC_CHANNEL_DISCONNECTED
- इंगित करता है कि दूरस्थ पक्ष ने नए कनेक्शन अनुरोध को अस्वीकार कर दिया है या पहले से जुड़े चैनल के लिए डिस्कनेक्शन का अनुरोध किया है -
TIPC_CHANNEL_SHUTDOWN
- इंगित करता है कि दूरस्थ पक्ष बंद हो रहा है, सभी कनेक्शन स्थायी रूप से समाप्त कर रहा है
struct tipc_msg_buf *(*handle_msg)(void *cb_arg, struct tipc_msg_buf *mb)
कॉलबैक को यह सूचना देने के लिए कहा जाता है कि एक निर्दिष्ट चैनल पर एक नया संदेश प्राप्त हुआ है:
- [में]
cb_arg
:tipc_create_channel()
कॉल को पास किए गए डेटा का सूचक - [में]
mb
: एक आने वाले संदेश का वर्णन करते हुए एक संरचना के लिए सूचकstruct tipc_msg_buf
- [रिटवल]: कॉलबैक कार्यान्वयन से एक
struct tipc_msg_buf
पर एक पॉइंटर वापस करने की उम्मीद है जो एकmb
पैरामीटर के रूप में प्राप्त एक ही पॉइंटर हो सकता है यदि संदेश स्थानीय रूप से संभाला जाता है और अब इसकी आवश्यकता नहीं है (या यह एक नया बफर प्राप्त किया जा सकता हैtipc_chan_get_rxbuf()
कॉल)
टिपक_चन_कनेक्ट ()
निर्दिष्ट भरोसेमंद आईपीसी सेवा के लिए एक कनेक्शन आरंभ करता है।
int tipc_chan_connect(struct tipc_chan *chan, const char *port);
[में] chan
: tipc_create_chan()
कॉल . द्वारा लौटाए गए चैनल का सूचक
[इन] port
: एक स्ट्रिंग के लिए पॉइंटर जिसमें सेवा का नाम होता है जिससे कनेक्ट करना है
[retval]: 0 सफलता पर, एक नकारात्मक त्रुटि अन्यथा
एक handle_event
कॉलबैक प्राप्त करके कनेक्शन स्थापित होने पर कॉलर को सूचित किया जाता है।
टिपक_चन_शटडाउन ()
एक tipc_chan_connect()
कॉल द्वारा पहले शुरू की गई भरोसेमंद आईपीसी सेवा से कनेक्शन को समाप्त करता है।
int tipc_chan_shutdown(struct tipc_chan *chan);
[में] chan
: एक tipc_create_chan()
कॉल द्वारा लौटाए गए चैनल के लिए सूचक
टिपक_चन_नष्ट ()
एक निर्दिष्ट भरोसेमंद आईपीसी चैनल को नष्ट कर देता है।
void tipc_chan_destroy(struct tipc_chan *chan);
[में] chan
: tipc_create_chan()
कॉल . द्वारा लौटाए गए चैनल का सूचक
टिपक_चन_गेट_टीक्सबफ_टाइमआउट ()
एक संदेश बफर प्राप्त करता है जिसका उपयोग निर्दिष्ट चैनल पर डेटा भेजने के लिए किया जा सकता है। यदि बफर तुरंत उपलब्ध नहीं है, तो कॉलर को निर्दिष्ट टाइमआउट (मिलीसेकंड में) के लिए ब्लॉक किया जा सकता है।
struct tipc_msg_buf * tipc_chan_get_txbuf_timeout(struct tipc_chan *chan, long timeout);
[में] chan
: उस चैनल का सूचक जिससे संदेश को कतारबद्ध करना है
[में] chan
: tx
बफ़र उपलब्ध होने तक प्रतीक्षा करने के लिए अधिकतम समयबाह्य
[retval]: सफलता पर एक वैध संदेश बफर, त्रुटि पर ERR_PTR(err)
टिपक_चन_क्यू_एमएसजी ()
निर्दिष्ट भरोसेमंद आईपीसी चैनलों पर भेजे जाने वाले संदेश को कतारबद्ध करता है।
int tipc_chan_queue_msg(struct tipc_chan *chan, struct tipc_msg_buf *mb);
[में] chan
: संदेश को कतारबद्ध करने के लिए चैनल के लिए सूचक
[में] mb:
कतार में संदेश के लिए सूचक (एक tipc_chan_get_txbuf_timeout()
कॉल द्वारा प्राप्त)
[retval]: 0 सफलता पर, एक नकारात्मक त्रुटि अन्यथा
टिपक_चन_पुट_टीएक्सबफ ()
tipc_chan_get_txbuf_timeout()
कॉल द्वारा पूर्व में प्राप्त निर्दिष्ट Tx
संदेश बफर को रिलीज करता है।
void tipc_chan_put_txbuf(struct tipc_chan *chan, struct tipc_msg_buf *mb);
[में] chan
: उस चैनल का सूचक जिससे यह संदेश बफ़र संबंधित है
[में] mb
: रिलीज करने के लिए संदेश बफर के लिए सूचक
[रिटवल]: कोई नहीं
टिपक_चन_गेट_आरएक्सबफ ()
एक नया संदेश बफ़र प्राप्त करता है जिसका उपयोग निर्दिष्ट चैनल पर संदेश प्राप्त करने के लिए किया जा सकता है।
struct tipc_msg_buf *tipc_chan_get_rxbuf(struct tipc_chan *chan);
[में] chan
: उस चैनल का सूचक जिससे यह संदेश बफ़र संबंधित है
[retval]: सफलता पर एक वैध संदेश बफर, त्रुटि पर ERR_PTR(err)
टिपक_चन_पुट_आरएक्सबफ ()
एक निर्दिष्ट संदेश बफ़र जारी करता है जिसे पहले एक tipc_chan_get_rxbuf()
कॉल द्वारा प्राप्त किया गया था।
void tipc_chan_put_rxbuf(struct tipc_chan *chan, struct tipc_msg_buf *mb);
[में] chan
: उस चैनल का सूचक जिससे यह संदेश बफ़र संबंधित है
[में] mb
: रिलीज करने के लिए एक संदेश बफर के लिए सूचक
[रिटवल]: कोई नहीं