LCOV - code coverage report
Current view: top level - nnstreamer-edge-0.2.6/src/libnnstreamer-edge - nnstreamer-edge-custom-impl.c (source / functions) Coverage Total Hit
Test: NNStreamer-edge 0.2.6-1 nnstreamer/nnstreamer-edge#121619a22eefb07aef74ab765d1eb0ec59b1416e Lines: 85.0 % 167 142
Test Date: 2025-06-06 05:20:40 Functions: 100.0 % 14 14

            Line data    Source code
       1              : /* SPDX-License-Identifier: Apache-2.0 */
       2              : /**
       3              :  * Copyright (C) 2024 Samsung Electronics Co., Ltd. All Rights Reserved.
       4              :  *
       5              :  * @file   nnstreamer-edge-custom-impl.c
       6              :  * @date   14 Aug 2024
       7              :  * @brief  Internal interface to support communication using custom library.
       8              :  * @see    https://github.com/nnstreamer/nnstreamer
       9              :  * @author Gichan Jang <gichan2.jang@samsung.com>
      10              :  * @bug    No known bugs except for NYI items
      11              :  */
      12              : 
      13              : #include <dlfcn.h>
      14              : 
      15              : #include "nnstreamer-edge-custom-impl.h"
      16              : #include "nnstreamer-edge-log.h"
      17              : #include "nnstreamer-edge-util.h"
      18              : 
      19              : /**
      20              :  * @brief Internal data structure for edge custom connection.
      21              :  */
      22              : typedef struct
      23              : {
      24              :   void *dl_handle;
      25              :   nns_edge_custom_s *instance;
      26              :   void *priv;
      27              : } custom_connection_s;
      28              : 
      29              : typedef const nns_edge_custom_s *custom_get_instance (void);
      30              : 
      31              : /**
      32              :  * @brief Internal function to load custom library.
      33              :  */
      34              : static int
      35            7 : _load_custom_library (custom_connection_s * custom, const char *lib_path)
      36              : {
      37              :   void *handle;
      38              :   nns_edge_custom_s *custom_h;
      39            7 :   int ret = NNS_EDGE_ERROR_UNKNOWN;
      40              : 
      41            7 :   handle = dlopen (lib_path, RTLD_LAZY);
      42            7 :   if (NULL == handle) {
      43            0 :     nns_edge_loge ("Failed to open custom library: %s", dlerror ());
      44            0 :     goto error;
      45              :   }
      46              : 
      47            7 :   custom_get_instance *get_instance =
      48            7 :       (custom_get_instance *) dlsym (handle, "nns_edge_custom_get_instance");
      49            7 :   if (!get_instance) {
      50            0 :     nns_edge_loge ("Failed to find nns_edge_custom_get_instance: %s",
      51              :         dlerror ());
      52            0 :     goto error;
      53              :   }
      54              : 
      55            7 :   custom_h = (nns_edge_custom_s *) get_instance ();
      56            7 :   if (!custom_h) {
      57            0 :     nns_edge_loge ("Failed to get custom instance from library.");
      58            0 :     goto error;
      59              :   }
      60              : 
      61            7 :   custom->dl_handle = handle;
      62            7 :   custom->instance = custom_h;
      63            7 :   ret = NNS_EDGE_ERROR_NONE;
      64              : 
      65            7 : error:
      66            7 :   if (NNS_EDGE_ERROR_NONE != ret) {
      67            0 :     if (handle)
      68            0 :       dlclose (handle);
      69              :   }
      70              : 
      71            7 :   return ret;
      72              : }
      73              : 
      74              : /**
      75              :  * @brief Internal function to load custom connection from library.
      76              :  */
      77              : int
      78           10 : nns_edge_custom_load (const char *lib_path,
      79              :     nns_edge_custom_connection_h * handle)
      80              : {
      81              :   custom_connection_s *custom;
      82              :   nns_edge_custom_s *custom_h;
      83              :   int ret;
      84              : 
      85           10 :   if (!STR_IS_VALID (lib_path))
      86            2 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
      87              : 
      88            8 :   if (!handle)
      89            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
      90              : 
      91            7 :   custom = (custom_connection_s *) calloc (1, sizeof (custom_connection_s));
      92            7 :   if (!custom) {
      93            0 :     nns_edge_loge ("Failed to allocate memory for edge custom connection.");
      94            0 :     return NNS_EDGE_ERROR_OUT_OF_MEMORY;
      95              :   }
      96              : 
      97            7 :   ret = _load_custom_library (custom, lib_path);
      98            7 :   if (NNS_EDGE_ERROR_NONE != ret) {
      99            0 :     nns_edge_loge
     100              :         ("Failed to load custom library. Please check the library path or permission.");
     101            0 :     goto error;
     102              :   }
     103              : 
     104            7 :   custom_h = custom->instance;
     105              : 
     106            7 :   ret = custom_h->nns_edge_custom_create (&custom->priv);
     107            7 :   if (NNS_EDGE_ERROR_NONE != ret) {
     108            0 :     nns_edge_loge ("Failed to create custom connection handle.");
     109              :   }
     110              : 
     111            7 : error:
     112            7 :   if (NNS_EDGE_ERROR_NONE == ret) {
     113            7 :     *handle = custom;
     114              :   } else {
     115            0 :     nns_edge_custom_release (custom);
     116              :   }
     117              : 
     118            7 :   return ret;
     119              : }
     120              : 
     121              : /**
     122              :  * @brief Internal function to release custom connection.
     123              :  */
     124              : int
     125            8 : nns_edge_custom_release (nns_edge_custom_connection_h handle)
     126              : {
     127            8 :   custom_connection_s *custom = (custom_connection_s *) handle;
     128              :   nns_edge_custom_s *custom_h;
     129              :   int ret;
     130              : 
     131            8 :   if (!custom || !custom->instance)
     132            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     133              : 
     134            7 :   custom_h = custom->instance;
     135              : 
     136            7 :   ret = custom_h->nns_edge_custom_close (custom->priv);
     137            7 :   if (NNS_EDGE_ERROR_NONE != ret) {
     138            0 :     nns_edge_loge ("Failed to stop custom connection.");
     139              :   }
     140              : 
     141            7 :   if (custom->dl_handle) {
     142            7 :     dlclose (custom->dl_handle);
     143              :   }
     144              : 
     145            7 :   custom->dl_handle = NULL;
     146            7 :   custom->instance = NULL;
     147            7 :   custom->priv = NULL;
     148              : 
     149            7 :   free (custom);
     150            7 :   return ret;
     151              : }
     152              : 
     153              : /**
     154              :  * @brief Internal function to start custom connection.
     155              :  */
     156              : int
     157            2 : nns_edge_custom_start (nns_edge_custom_connection_h handle)
     158              : {
     159            2 :   custom_connection_s *custom = (custom_connection_s *) handle;
     160              :   nns_edge_custom_s *custom_h;
     161              :   int ret;
     162              : 
     163            2 :   if (!custom || !custom->instance)
     164            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     165              : 
     166            1 :   custom_h = custom->instance;
     167              : 
     168            1 :   ret = custom_h->nns_edge_custom_start (custom->priv);
     169            1 :   if (NNS_EDGE_ERROR_NONE != ret) {
     170            0 :     nns_edge_loge ("Failed to start custom connection.");
     171              :   }
     172              : 
     173            1 :   return ret;
     174              : }
     175              : 
     176              : /**
     177              :  * @brief Internal function to stop custom connection.
     178              :  */
     179              : int
     180            2 : nns_edge_custom_stop (nns_edge_custom_connection_h handle)
     181              : {
     182            2 :   custom_connection_s *custom = (custom_connection_s *) handle;
     183              :   nns_edge_custom_s *custom_h;
     184              :   int ret;
     185              : 
     186            2 :   if (!custom || !custom->instance)
     187            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     188              : 
     189            1 :   custom_h = custom->instance;
     190              : 
     191            1 :   ret = custom_h->nns_edge_custom_stop (custom->priv);
     192            1 :   if (NNS_EDGE_ERROR_NONE != ret) {
     193            0 :     nns_edge_loge ("Failed to stop custom connection.");
     194              :   }
     195              : 
     196            1 :   return ret;
     197              : }
     198              : 
     199              : /**
     200              :  * @brief Internal function to set the event callback of custom connection.
     201              :  */
     202              : int
     203            2 : nns_edge_custom_set_event_callback (nns_edge_custom_connection_h handle,
     204              :     nns_edge_event_cb cb, void *user_data)
     205              : {
     206            2 :   custom_connection_s *custom = (custom_connection_s *) handle;
     207              :   nns_edge_custom_s *custom_h;
     208              :   int ret;
     209              : 
     210            2 :   if (!custom || !custom->instance)
     211            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     212              : 
     213            1 :   custom_h = custom->instance;
     214              : 
     215            1 :   ret = custom_h->nns_edge_custom_set_event_cb (custom->priv, cb, user_data);
     216            1 :   if (NNS_EDGE_ERROR_NONE != ret) {
     217            0 :     nns_edge_loge ("Failed to set event callback to custom connection.");
     218              :   }
     219              : 
     220            1 :   return ret;
     221              : }
     222              : 
     223              : /**
     224              :  * @brief Internal function to start discovery devices of custom connection.
     225              :  */
     226              : int
     227            2 : nns_edge_custom_start_discovery (nns_edge_custom_connection_h handle)
     228              : {
     229            2 :   custom_connection_s *custom = (custom_connection_s *) handle;
     230              :   nns_edge_custom_s *custom_h;
     231              :   int ret;
     232              : 
     233            2 :   if (!custom || !custom->instance)
     234            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     235              : 
     236            1 :   custom_h = custom->instance;
     237              : 
     238            1 :   ret = custom_h->nns_edge_custom_start_discovery (custom->priv);
     239            1 :   if (NNS_EDGE_ERROR_NONE != ret) {
     240            0 :     nns_edge_loge ("Failed to start discovery devices of custom connection.");
     241              :   }
     242              : 
     243            1 :   return ret;
     244              : }
     245              : 
     246              : /**
     247              :  * @brief Internal function to stop discovery devices of custom connection.
     248              :  */
     249              : int
     250            2 : nns_edge_custom_stop_discovery (nns_edge_custom_connection_h handle)
     251              : {
     252            2 :   custom_connection_s *custom = (custom_connection_s *) handle;
     253              :   nns_edge_custom_s *custom_h;
     254              :   int ret;
     255              : 
     256            2 :   if (!custom || !custom->instance)
     257            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     258              : 
     259            1 :   custom_h = custom->instance;
     260              : 
     261            1 :   ret = custom_h->nns_edge_custom_stop_discovery (custom->priv);
     262            1 :   if (NNS_EDGE_ERROR_NONE != ret) {
     263            0 :     nns_edge_loge ("Failed to stop discovery devices of custom connection.");
     264              :   }
     265              : 
     266            1 :   return ret;
     267              : }
     268              : 
     269              : /**
     270              :  * @brief Internal function to connect custom connection.
     271              :  */
     272              : int
     273            3 : nns_edge_custom_connect (nns_edge_custom_connection_h handle)
     274              : {
     275            3 :   custom_connection_s *custom = (custom_connection_s *) handle;
     276              :   nns_edge_custom_s *custom_h;
     277              :   int ret;
     278              : 
     279            3 :   if (!custom || !custom->instance)
     280            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     281              : 
     282            2 :   custom_h = custom->instance;
     283              : 
     284            2 :   ret = custom_h->nns_edge_custom_connect (custom->priv);
     285            2 :   if (NNS_EDGE_ERROR_NONE != ret) {
     286            0 :     nns_edge_loge ("Failed to connect custom connection.");
     287              :   }
     288              : 
     289            2 :   return ret;
     290              : }
     291              : 
     292              : /**
     293              :  * @brief Internal function to disconnect custom connection.
     294              :  */
     295              : int
     296            2 : nns_edge_custom_disconnect (nns_edge_custom_connection_h handle)
     297              : {
     298            2 :   custom_connection_s *custom = (custom_connection_s *) handle;
     299              :   nns_edge_custom_s *custom_h;
     300              :   int ret;
     301              : 
     302            2 :   if (!custom || !custom->instance)
     303            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     304              : 
     305            1 :   custom_h = custom->instance;
     306              : 
     307            1 :   ret = custom_h->nns_edge_custom_disconnect (custom->priv);
     308            1 :   if (NNS_EDGE_ERROR_NONE != ret) {
     309            0 :     nns_edge_loge ("Failed to disconnect custom connection.");
     310              :   }
     311              : 
     312            1 :   return ret;
     313              : }
     314              : 
     315              : /**
     316              :  * @brief Internal function to check custom connection.
     317              :  */
     318              : int
     319            8 : nns_edge_custom_is_connected (nns_edge_custom_connection_h handle)
     320              : {
     321            8 :   custom_connection_s *custom = (custom_connection_s *) handle;
     322              :   nns_edge_custom_s *custom_h;
     323              : 
     324            8 :   if (!custom || !custom->instance)
     325            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     326              : 
     327            7 :   custom_h = custom->instance;
     328              : 
     329            7 :   return custom_h->nns_edge_custom_is_connected (custom->priv);
     330              : }
     331              : 
     332              : /**
     333              :  * @brief Internal function to send data to custom connection.
     334              :  */
     335              : int
     336            3 : nns_edge_custom_send_data (nns_edge_custom_connection_h handle,
     337              :     nns_edge_data_h data_h)
     338              : {
     339            3 :   custom_connection_s *custom = (custom_connection_s *) handle;
     340              :   nns_edge_custom_s *custom_h;
     341              :   int ret;
     342              : 
     343            3 :   if (!custom || !custom->instance)
     344            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     345              : 
     346            2 :   ret = nns_edge_data_is_valid (data_h);
     347            2 :   if (NNS_EDGE_ERROR_NONE != ret)
     348            1 :     return ret;
     349              : 
     350            1 :   custom_h = custom->instance;
     351              : 
     352            1 :   ret = custom_h->nns_edge_custom_send_data (custom->priv, data_h);
     353            1 :   if (NNS_EDGE_ERROR_NONE != ret) {
     354            0 :     nns_edge_loge ("Failed to send data to custom connection.");
     355              :   }
     356              : 
     357            1 :   return ret;
     358              : }
     359              : 
     360              : /**
     361              :  * @brief Internal function to set information to custom connection.
     362              :  */
     363              : int
     364            6 : nns_edge_custom_set_info (nns_edge_custom_connection_h handle, const char *key,
     365              :     const char *value)
     366              : {
     367            6 :   custom_connection_s *custom = (custom_connection_s *) handle;
     368              :   nns_edge_custom_s *custom_h;
     369            6 :   int ret = NNS_EDGE_ERROR_NOT_SUPPORTED;
     370              : 
     371            6 :   if (!custom || !custom->instance)
     372            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     373              : 
     374            5 :   if (!STR_IS_VALID (key) || !STR_IS_VALID (value))
     375            4 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     376              : 
     377            1 :   custom_h = custom->instance;
     378              : 
     379            1 :   if (custom_h->nns_edge_custom_set_info) {
     380            1 :     ret = custom_h->nns_edge_custom_set_info (custom->priv, key, value);
     381            1 :     if (NNS_EDGE_ERROR_NONE != ret) {
     382            0 :       nns_edge_loge ("Failed to set information to custom connection.");
     383              :     }
     384              :   }
     385              : 
     386            1 :   return ret;
     387              : }
     388              : 
     389              : /**
     390              :  * @brief Internal function to get information from custom connection.
     391              :  */
     392              : int
     393            5 : nns_edge_custom_get_info (nns_edge_custom_connection_h handle, const char *key,
     394              :     char **value)
     395              : {
     396            5 :   custom_connection_s *custom = (custom_connection_s *) handle;
     397              :   nns_edge_custom_s *custom_h;
     398            5 :   int ret = NNS_EDGE_ERROR_NOT_SUPPORTED;
     399              : 
     400            5 :   if (!custom || !custom->instance)
     401            1 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     402              : 
     403            4 :   if (!STR_IS_VALID (key) || !value)
     404            3 :     return NNS_EDGE_ERROR_INVALID_PARAMETER;
     405              : 
     406            1 :   custom_h = custom->instance;
     407              : 
     408            1 :   if (custom_h->nns_edge_custom_get_info) {
     409            1 :     ret = custom_h->nns_edge_custom_get_info (custom->priv, key, value);
     410            1 :     if (NNS_EDGE_ERROR_NONE != ret) {
     411            0 :       nns_edge_loge ("Failed to get information from custom connection.");
     412              :     }
     413              :   }
     414              : 
     415            1 :   return ret;
     416              : }
        

Generated by: LCOV version 2.0-1