भरोसेमंद एपीआई संदर्भ

ट्रस्टी अनुप्रयोगों/सेवाओं के दो वर्गों को विकसित करने के लिए एपीआई प्रदान करता है:

  • विश्वसनीय एप्लिकेशन या सेवाएँ जो TEE प्रोसेसर पर चलती हैं
  • सामान्य/अविश्वसनीय एप्लिकेशन जो मुख्य प्रोसेसर पर चलते हैं और विश्वसनीय एप्लिकेशन द्वारा प्रदान की गई सेवाओं का उपयोग करते हैं

ट्रस्टी एपीआई आम तौर पर ट्रस्टी अंतर-प्रक्रिया संचार (आईपीसी) प्रणाली का वर्णन करता है, जिसमें गैर-सुरक्षित दुनिया के साथ संचार भी शामिल है। मुख्य प्रोसेसर पर चलने वाला सॉफ़्टवेयर विश्वसनीय अनुप्रयोगों/सेवाओं से जुड़ने और आईपी पर नेटवर्क सेवा की तरह उनके साथ मनमाने संदेशों का आदान-प्रदान करने के लिए भरोसेमंद एपीआई का उपयोग कर सकता है। ऐप-स्तरीय प्रोटोकॉल का उपयोग करके इन संदेशों के डेटा प्रारूप और शब्दार्थ को निर्धारित करना एप्लिकेशन पर निर्भर है। संदेशों की विश्वसनीय डिलीवरी की गारंटी अंतर्निहित भरोसेमंद बुनियादी ढांचे (मुख्य प्रोसेसर पर चलने वाले ड्राइवरों के रूप में) द्वारा की जाती है, और संचार पूरी तरह से अतुल्यकालिक है।

बंदरगाह और चैनल

पोर्ट का उपयोग भरोसेमंद अनुप्रयोगों द्वारा नामित पथ के रूप में सेवा अंत-बिंदुओं को उजागर करने के लिए किया जाता है जिससे ग्राहक जुड़ते हैं। यह ग्राहकों को उपयोग के लिए एक सरल, स्ट्रिंग-आधारित सेवा आईडी देता है। नामकरण परंपरा रिवर्स-डीएनएस-शैली नामकरण है, उदाहरण के लिए com.google.servicename

जब कोई क्लाइंट किसी पोर्ट से कनेक्ट होता है, तो क्लाइंट को किसी सेवा के साथ इंटरैक्ट करने के लिए एक चैनल प्राप्त होता है। सेवा को आने वाले कनेक्शन को स्वीकार करना होगा, और जब वह ऐसा करती है, तो उसे भी एक चैनल प्राप्त होता है। संक्षेप में, बंदरगाहों का उपयोग सेवाओं को देखने के लिए किया जाता है और फिर संचार जुड़े चैनलों की एक जोड़ी पर होता है (यानी, बंदरगाह पर कनेक्शन उदाहरण)। जब कोई क्लाइंट किसी पोर्ट से जुड़ता है, तो एक सममित, द्वि-दिशात्मक कनेक्शन स्थापित होता है। इस पूर्ण-डुप्लेक्स पथ का उपयोग करके, क्लाइंट और सर्वर मनमाने संदेशों का आदान-प्रदान कर सकते हैं जब तक कि दोनों पक्ष कनेक्शन को तोड़ने का निर्णय नहीं लेते।

केवल सुरक्षित-पक्षीय विश्वसनीय एप्लिकेशन या भरोसेमंद कर्नेल मॉड्यूल ही पोर्ट बना सकते हैं। गैर-सुरक्षित पक्ष (सामान्य दुनिया में) पर चलने वाले एप्लिकेशन केवल सुरक्षित पक्ष द्वारा प्रकाशित सेवाओं से जुड़ सकते हैं।

आवश्यकताओं के आधार पर, एक विश्वसनीय एप्लिकेशन एक ही समय में क्लाइंट और सर्वर दोनों हो सकता है। एक विश्वसनीय एप्लिकेशन जो एक सेवा (सर्वर के रूप में) प्रकाशित करता है, उसे अन्य सेवाओं (क्लाइंट के रूप में) से कनेक्ट करने की आवश्यकता हो सकती है।

एपीआई संभालें

हैंडल अहस्ताक्षरित पूर्णांक हैं जो UNIX में फ़ाइल डिस्क्रिप्टर के समान पोर्ट और चैनल जैसे संसाधनों का प्रतिनिधित्व करते हैं। हैंडल बनाए जाने के बाद, उन्हें एप्लिकेशन-विशिष्ट हैंडल तालिका में रखा जाता है और बाद में संदर्भित किया जा सकता है।

एक कॉलर set_cookie() विधि का उपयोग करके निजी डेटा को एक हैंडल के साथ जोड़ सकता है।

हैंडल एपीआई में विधियाँ

हैंडल केवल किसी एप्लिकेशन के संदर्भ में मान्य हैं। जब तक स्पष्ट रूप से निर्दिष्ट न किया जाए, किसी एप्लिकेशन को किसी हैंडल का मान अन्य एप्लिकेशन को पास नहीं करना चाहिए। एक हैंडल मान की व्याख्या केवल INVALID_IPC_HANDLE #define, जिसे एक एप्लिकेशन एक संकेत के रूप में उपयोग कर सकता है कि एक हैंडल अमान्य या अनसेट है।

कॉलर द्वारा प्रदत्त निजी डेटा को एक निर्दिष्ट हैंडल के साथ संबद्ध करता है।

long set_cookie(uint32_t handle, void *cookie)

[इन] handle : एपीआई कॉल में से किसी एक द्वारा लौटाया गया कोई भी हैंडल

[में] cookie : भरोसेमंद एप्लिकेशन में मनमाने ढंग से उपयोगकर्ता-स्थान डेटा का सूचक

[रिटवल]: सफलता पर NO_ERROR , अन्यथा < 0 त्रुटि कोड

यह कॉल उन घटनाओं को संभालने के लिए उपयोगी है जब वे हैंडल बनने के बाद बाद में घटित होती हैं। इवेंट-हैंडलिंग तंत्र हैंडल और उसकी कुकी को इवेंट हैंडलर को वापस आपूर्ति करता है।

wait() कॉल का उपयोग करके घटनाओं के लिए हैंडल का इंतजार किया जा सकता है।

इंतज़ार()

निर्दिष्ट समयावधि के लिए किसी दिए गए हैंडल पर किसी घटना के घटित होने की प्रतीक्षा करता है।

long wait(uint32_t handle_id, uevent_t *event, unsigned long timeout_msecs)

[में] handle_id : एपीआई कॉल में से किसी एक द्वारा लौटाया गया कोई भी हैंडल

[बाहर] event : इस हैंडल पर हुई घटना का प्रतिनिधित्व करने वाली संरचना का एक सूचक

[में] timeout_msecs : मिलीसेकंड में एक टाइमआउट मान; -1 का मान एक अनंत टाइमआउट है

[रिटवल]: 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 : नष्ट करने के लिए हैंडल

[रिटवल]: 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 - गैर-सुरक्षित दुनिया से कनेक्शन की अनुमति देता है

[रिटवल]: गैर-नकारात्मक होने पर बनाए गए पोर्ट को हैंडल करें या नकारात्मक होने पर एक विशिष्ट त्रुटि

सर्वर तब wait() कॉल का उपयोग करके आने वाले कनेक्शन के लिए पोर्ट हैंडल की सूची का चुनाव करता है। uevent_t संरचना के event फ़ील्ड में IPC_HANDLE_POLL_READY बिट सेट द्वारा इंगित कनेक्शन अनुरोध प्राप्त होने पर, सर्वर को कनेक्शन स्थापित करने और एक चैनल (किसी अन्य हैंडल द्वारा दर्शाया गया) बनाने के लिए accept() कॉल करना चाहिए जिसे आने वाले संदेशों के लिए पोल किया जा सकता है। .

स्वीकार करना()

आने वाले कनेक्शन को स्वीकार करता है और एक चैनल के लिए हैंडल प्राप्त करता है।

long accept(uint32_t handle_id, uuid_t *peer_uuid);

[में] handle_id : हैंडल उस पोर्ट का प्रतिनिधित्व करता है जिससे क्लाइंट कनेक्ट हुआ है

[आउट] peer_uuid : कनेक्टिंग क्लाइंट एप्लिकेशन के यूयूआईडी से भरे जाने वाले uuid_t संरचना का सूचक। यदि कनेक्शन गैर-सुरक्षित दुनिया से उत्पन्न हुआ है तो यह सभी शून्य पर सेट हो जाएगा

[रिटवल]: एक चैनल को संभालें (यदि गैर-नकारात्मक) जिस पर सर्वर क्लाइंट के साथ संदेशों का आदान-प्रदान कर सकता है (या अन्यथा एक त्रुटि कोड)

क्लाइंट एपीआई

इस अनुभाग में क्लाइंट एपीआई में विधियाँ शामिल हैं।

क्लाइंट एपीआई में विधियाँ

जोड़ना()

नाम द्वारा निर्दिष्ट पोर्ट से कनेक्शन आरंभ करता है।

long connect(const char *path, uint flags);

[में] path : एक भरोसेमंद एप्लिकेशन द्वारा प्रकाशित पोर्ट का नाम

[में] flags : अतिरिक्त, वैकल्पिक व्यवहार निर्दिष्ट करता है

[रिटवल]: एक चैनल को संभालें जिस पर सर्वर के साथ संदेशों का आदान-प्रदान किया जा सकता है; यदि नकारात्मक है तो त्रुटि

यदि कोई 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 सरणी द्वारा वर्णित बफ़र्स की सामग्री पूरी तरह से मनमानी है।

मैसेजिंग एपीआई में विधियाँ

भेजें_संदेश()

एक निर्दिष्ट चैनल पर एक संदेश भेजता है।

long send_msg(uint32_t handle, ipc_msg_t *msg);

[इन] handle : उस चैनल को हैंडल करें जिस पर संदेश भेजना है

[in] msg : संदेश का वर्णन करने वाली ipc_msg_t structure का सूचक

[रिटवल]: सफलता पर भेजे गए बाइट्स की कुल संख्या; अन्यथा एक नकारात्मक त्रुटि

यदि क्लाइंट (या सर्वर) चैनल पर एक संदेश भेजने का प्रयास कर रहा है और गंतव्य सहकर्मी संदेश कतार में कोई जगह नहीं है, तो चैनल एक सेंड-अवरुद्ध स्थिति में प्रवेश कर सकता है (सरल सिंक्रोनस अनुरोध/उत्तर प्रोटोकॉल के लिए ऐसा कभी नहीं होना चाहिए) लेकिन अधिक जटिल मामलों में ऐसा हो सकता है) जो कि ERR_NOT_ENOUGH_BUFFER त्रुटि कोड लौटाकर दर्शाया गया है। ऐसे मामले में कॉल करने वाले को तब तक इंतजार करना होगा जब तक कि सहकर्मी हैंडलिंग और रिटायरिंग संदेशों को पुनः प्राप्त करके अपनी प्राप्त कतार में कुछ स्थान खाली नहीं कर देता है, जो wait() कॉल द्वारा लौटाए गए uevent_t संरचना के event फ़ील्ड में सेट IPC_HANDLE_POLL_SEND_UNBLOCKED बिट द्वारा इंगित किया गया है।

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;

प्रत्येक संदेश को बकाया संदेशों के सेट में एक अद्वितीय आईडी सौंपी जाती है, और प्रत्येक संदेश की कुल लंबाई भरी जाती है। यदि प्रोटोकॉल द्वारा कॉन्फ़िगर और अनुमति दी जाती है, तो किसी विशेष चैनल के लिए एक साथ कई बकाया (खुले) संदेश हो सकते हैं।

[रिटवल]: सफलता पर NO_ERROR ; अन्यथा एक नकारात्मक त्रुटि

read_msg()

निर्दिष्ट ऑफसेट से प्रारंभ करके निर्दिष्ट आईडी के साथ संदेश की सामग्री को पढ़ता है।

long read_msg(uint32_t handle, uint32_t msg_id, uint32_t offset, ipc_msg_t
*msg);

[इन] handle : उस चैनल का हैंडल जिससे संदेश पढ़ना है

[in] msg_id : पढ़ने के लिए संदेश की आईडी

[इन] offset : उस संदेश में ऑफसेट करें जिससे पढ़ना शुरू करना है

[बाहर] msg : ipc_msg_t संरचना का सूचक जो बफ़र्स के एक सेट का वर्णन करता है जिसमें आने वाले संदेश डेटा को संग्रहीत किया जाता है

[रिटवल]: सफलता पर msg बफ़र्स में संग्रहीत बाइट्स की कुल संख्या; अन्यथा एक नकारात्मक त्रुटि

आवश्यकतानुसार read_msg विधि को अलग-अलग (जरूरी नहीं कि अनुक्रमिक नहीं) ऑफसेट से शुरू करके कई बार कॉल किया जा सकता है।

put_msg()

एक निर्दिष्ट आईडी के साथ एक संदेश को रिटायर करता है।

long put_msg(uint32_t handle, uint32_t msg_id);

[इन] handle : उस चैनल का हैंडल जिस पर संदेश आया है

[in] msg_id : संदेश की आईडी समाप्त की जा रही है

[रिटवल]: सफलता पर 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 : पढ़ने के लिए बाइट्स की अधिकतम संख्या

[रिटवल]: पढ़े गए बाइट्स की लौटाई गई संख्या; अन्यथा एक नकारात्मक त्रुटि

लिखना()

निर्दिष्ट फ़ाइल डिस्क्रिप्टर में डेटा के बाइट्स की count तक लिखता है।

long write(uint32_t fd, void *buf, uint32_t count);

[में] fd : फ़ाइल डिस्क्रिप्टर जिस पर लिखना है

[बाहर] buf : लिखने के लिए डेटा का सूचक

[में] count : लिखने के लिए बाइट्स की अधिकतम संख्या

[रिटवल]: लिखे गए बाइट्स की लौटाई गई संख्या; अन्यथा एक नकारात्मक त्रुटि

ioctl()

किसी दिए गए फ़ाइल डिस्क्रिप्टर के लिए निर्दिष्ट ioctl कमांड को आमंत्रित करता है।

long ioctl(uint32_t fd, uint32_t cmd, void *args);

[में] fd : फ़ाइल डिस्क्रिप्टर जिस पर ioctl() लागू करना है

[में] cmd : ioctl कमांड

[अंदर/बाहर] args : ioctl() तर्कों का सूचक

विविध एपीआई

विविध एपीआई में विधियाँ

समय निकालो()

वर्तमान सिस्टम समय (नैनोसेकंड में) लौटाता है।

long gettime(uint32_t clock_id, uint32_t flags, int64_t *time);

[में] clock_id : प्लेटफ़ॉर्म-निर्भर; डिफ़ॉल्ट के लिए शून्य पास करें

[में] flags : आरक्षित, शून्य होना चाहिए

[बाहर] time : वर्तमान समय को संग्रहीत करने के लिए int64_t मान का सूचक

[रिटवल]: सफलता पर NO_ERROR ; अन्यथा एक नकारात्मक त्रुटि

नैनोस्लीप()

कॉलिंग एप्लिकेशन के निष्पादन को एक निर्दिष्ट अवधि के लिए निलंबित कर देता है और उस अवधि के बाद इसे फिर से शुरू करता है।

long nanosleep(uint32_t clock_id, uint32_t flags, uint64_t sleep_time)

[में] clock_id : आरक्षित, शून्य होना चाहिए

[में] flags : आरक्षित, शून्य होना चाहिए

[में] sleep_time : सोने का समय नैनोसेकंड में

[रिटवल]: सफलता पर 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() कॉल एक फ़ाइल डिस्क्रिप्टर प्राप्त करने के लिए एक निर्दिष्ट डिवाइस नोड खोलता है और argp पैरामीटर के साथ एक TIPC_IOC_CONNECT ioctl() कॉल को आमंत्रित करता है जो एक सेवा नाम वाली स्ट्रिंग की ओर इशारा करता है जिससे कनेक्ट करना है।

#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() पुकारना।

टिपसी_कनेक्ट()

एक निर्दिष्ट tipc डिवाइस नोड खोलता है और एक निर्दिष्ट भरोसेमंद सेवा से कनेक्शन शुरू करता है।

int tipc_connect(const char *dev_name, const char *srv_name);

[में] dev_name : भरोसेमंद आईपीसी डिवाइस नोड को खोलने का पथ

[in] srv_name : एक प्रकाशित भरोसेमंद सेवा का नाम जिससे जुड़ना है

[रिटवल]: सफलता पर वैध फ़ाइल डिस्क्रिप्टर, अन्यथा -1।

टिपसी_क्लोज़()

फ़ाइल डिस्क्रिप्टर द्वारा निर्दिष्ट भरोसेमंद सेवा से कनेक्शन बंद कर देता है।

int tipc_close(int fd);

[में] 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);

[in] chan : tipc_create_chan() कॉल द्वारा लौटाए गए चैनल का सूचक

[इन] port : एक स्ट्रिंग का सूचक जिसमें सेवा का नाम शामिल है जिससे कनेक्ट करना है

[रिटवल]: सफलता पर 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);

[in] chan : tipc_create_chan() कॉल द्वारा लौटाए गए चैनल का सूचक

टिपसी_चान_गेट_txbuf_timeout()

एक संदेश बफ़र प्राप्त करता है जिसका उपयोग किसी निर्दिष्ट चैनल पर डेटा भेजने के लिए किया जा सकता है। यदि बफ़र तुरंत उपलब्ध नहीं है तो कॉल करने वाले को निर्दिष्ट टाइमआउट (मिलीसेकंड में) के लिए ब्लॉक किया जा सकता है।

struct tipc_msg_buf *
tipc_chan_get_txbuf_timeout(struct tipc_chan *chan, long timeout);

[इन] chan : उस चैनल का सूचक जिस पर संदेश कतारबद्ध करना है

[में] chan : tx बफर उपलब्ध होने तक प्रतीक्षा करने के लिए अधिकतम समयबाह्य

[रिटवल]: सफलता पर एक वैध संदेश बफ़र, त्रुटि पर ERR_PTR(err)

टिपसी_चान_क्यू_एमएसजी()

निर्दिष्ट भरोसेमंद आईपीसी चैनलों पर भेजे जाने वाले संदेश को कतारबद्ध करता है।

int tipc_chan_queue_msg(struct tipc_chan *chan, struct tipc_msg_buf *mb);

[इन] chan : उस चैनल का सूचक जिस पर संदेश को कतारबद्ध करना है

[में] mb: कतार में भेजे जाने वाले संदेश का सूचक ( tipc_chan_get_txbuf_timeout() कॉल द्वारा प्राप्त)

[रिटवल]: सफलता पर 0, अन्यथा एक नकारात्मक त्रुटि

टिपसी_चान_पुट_txbuf()

पहले से एक 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 : उस चैनल का सूचक जिससे यह संदेश बफ़र संबंधित है

[रिटवल]: सफलता पर एक वैध संदेश बफ़र, त्रुटि पर ERR_PTR(err)

टिपसी_चान_पुट_आरएक्सबफ()

एक निर्दिष्ट संदेश बफ़र जारी करता है जो पहले एक tipc_chan_get_rxbuf() कॉल द्वारा प्राप्त किया गया था।

void tipc_chan_put_rxbuf(struct tipc_chan *chan,
                         struct tipc_msg_buf *mb);

[इन] chan : उस चैनल का सूचक जिससे यह संदेश बफ़र संबंधित है

[में] mb : जारी किए जाने वाले संदेश बफ़र का सूचक

[रिट्वल]: कोई नहीं