botsense  3.2.0
RoadNarrows Client-Server Proxied Services Framework
bsProxyMod.c
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: BotSense
4 //
5 // Program: bsProxy
6 //
7 // File: bsProxyMod.c
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2010-08-20 11:36:38 -0600 (Fri, 20 Aug 2010) $
12  * $Rev: 568 $
13  *
14  * \brief Proxied interface module management operations.
15  *
16  * \sa http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html
17  *
18  * \author Robin Knight (robin.knight@roadnarrows.com)
19  *
20  * \copyright
21  * \h_copy 2010-2017. RoadNarrows LLC.\n
22  * http://www.roadnarrows.com\n
23  * All Rights Reserved
24  */
25 // Permission is hereby granted, without written agreement and without
26 // license or royalty fees, to use, copy, modify, and distribute this
27 // software and its documentation for any purpose, provided that
28 // (1) The above copyright notice and the following two paragraphs
29 // appear in all copies of the source code and (2) redistributions
30 // including binaries reproduces these notices in the supporting
31 // documentation. Substantial modifications to this software may be
32 // copyrighted by their authors and need not follow the licensing terms
33 // described here, provided that the new terms are clearly indicated in
34 // all files where they apply.
35 //
36 // IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES
37 // OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
38 // PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
39 // DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
40 // EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
41 // THE POSSIBILITY OF SUCH DAMAGE.
42 //
43 // THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
44 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
45 // FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
46 // "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
47 // PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
48 //
49 ////////////////////////////////////////////////////////////////////////////////
50 
51 #include <limits.h>
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <stdarg.h>
55 #include <string.h>
56 #include <errno.h>
57 #include <pthread.h>
58 #include <dlfcn.h>
59 
60 #include "rnr/rnrconfig.h"
61 #include "rnr/log.h"
62 #include "rnr/new.h"
63 #include "rnr/hash.h"
64 #include "rnr/dliststr.h"
65 #include "rnr/path.h"
66 
67 #include "botsense/BotSense.h"
68 #include "botsense/bsProxyModIF.h"
69 #include "botsense/bsProxyMsgs.h"
70 
71 #include "bsProxy.h"
72 
73 
74 // ---------------------------------------------------------------------------
75 // Private Interface
76 // ---------------------------------------------------------------------------
77 
78 #ifndef __windows__
79 # define DLL_EXT ".so" ///< standard dll library file name extension
80 #else
81 # define DLL_EXT ".DLL" ///< windows dll library file name extension
82 #endif
83 
84 #ifndef BS_AUX_LIBDIR
85 #define BS_AUX_LIBDIR "/prj/lib" ///< additional bsProxy library directory
86 #endif
87 
88 #ifndef BS_PLUGIN_DIR
89 #define BS_PLUGIN_DIR "." ///< bsProxy module plugin subdirectory
90 #endif
91 
92 #define BSPROXY_MOD_HASH_MIN 32 ///< minimum hash table size
93 #define BSPROXY_MOD_HASH_MAX 256 ///< maximum hash table size
94 
95 static pthread_mutex_t BsModMutex; ///< bsProxy module operations mutex
96 static hash_t *BsModHashTbl; ///< i/f module hash table
97 static DListStr_T *BsModDllPaths; ///< module search paths
98 
99 /*!
100  * \brief Log Proxy Server Module Error.
101  *
102  * \param moduri Module URI string.
103  * \param ecode \h_botsense error code.
104  * \param efmt Error output format string literal.
105  * \param ... Error variable arguments.
106  */
107 #define BSPROXY_MOD_LOG_ERROR(moduri, ecode, efmt, ...) \
108  LOGERROR("%s: \"%s\": %s(ecode=%d): " efmt, \
109  ServerHasName(), moduri, \
110  bsStrError(ecode), (ecode>=0? ecode: -ecode), \
111  ##__VA_ARGS__)
112 
113 
114 //.............................................................................
115 // Mutual Exclusion Functions
116 //.............................................................................
117 
118 /*!
119  * \brief Lock module's global mutual exclusion.
120  */
121 static inline void ModLock()
122 {
123  int rc;
124 
125  if( (rc = pthread_mutex_lock(&BsModMutex)) != 0 )
126  {
127  errno = rc;
128  LOGSYSERROR("pthread_mutex_lock()");
129  }
130 }
131 
132 /*!
133  * \brief Unlock module's global mutual exclusion.
134  */
135 static inline void ModUnlock()
136 {
137  int rc;
138 
139  if( (rc = pthread_mutex_unlock(&BsModMutex)) != 0 )
140  {
141  errno = rc;
142  LOGSYSERROR("pthread_mutex_unlock()");
143  }
144 }
145 
146 /*!
147  * \brief Try to lock module's global mutual exclusion.
148  *
149  * \return
150  * Returns true if lock is acquired. Otherwise returns false if mutex already
151  * locked.
152  */
153 static inline bool_t ModTryLock()
154 {
155  return pthread_mutex_trylock(&BsModMutex) == 0? true: false;
156 }
157 
158 
159 //.............................................................................
160 // Dynamic Link Loader Functions
161 //.............................................................................
162 
163 /*!
164  * Initialize Dynamic Link Loader operating parameters.
165  *
166  * \param pDListLibPath List of optional library search paths.
167  *
168  * For i/f module search path order:
169  * \li command-line -L options in order listed
170  * \li XML configuration paths
171  * \li user's home lib directory if it exists
172  * \li \h_botsense library install library path
173  * \li default dlopen() locations (system dependent)
174  */
175 static void ModDllInit(DListStr_T *pDListLibPath)
176 {
177  DListStrIter_T iter;
178  char *sLibPath;
179  char *sPath;
180 
181  BsModDllPaths = DListStrNewDft();
182 
183  // Add command-line -L paths here
184  for(sLibPath=DListStrIterDataFirst(pDListLibPath, &iter);
185  sLibPath!=NULL;
186  sLibPath=DListStrIterDataNext(&iter))
187  {
188  // canonicalize path name
189  if( (sPath = NewSearchPathCanonicalized(sLibPath)) == NULL )
190  {
191  LOGDIAG2("Warning: \"%s\": Ignoring bad library path.", sLibPath);
192  }
193  else
194  {
195  DListStrAppend(BsModDllPaths, sPath);
196  }
197  }
198 
199  // RDK add xml config paths here
200 
201  // RDK add user's home/botsense/libs path here
202 
203  // Add installed prefix/lib/botsense/ path.
204  if( (sPath = NewJoinedPath(BS_AUX_LIBDIR, BS_PLUGIN_DIR)) != NULL )
205  {
206  DListStrAppend(BsModDllPaths, sPath);
207  }
208 }
209 
210 /*!
211  * \brief Make DLL canonical file name.
212  *
213  * The library path is expanded, canonicalized and any necessary file extension is
214  * appended.
215  *
216  * \param sModName DLL library path name.
217  *
218  * \return
219  * On success, an allocated, canonical library path name is returned.\n
220  * On failure, NULL is returned.
221  */
222 static char *ModDllNewCanonicalName(const char *sModName)
223 {
224  char *s = NULL;
225  char *t = NULL;
226  size_t m, n;
227 
228  // canonicalize module path name
229  if( (s = NewSearchPathCanonicalized(sModName)) == NULL )
230  {
231  LOGERROR("NewSearchPathCanonicalized(\"%s\") failed.", sModName);
232  return NULL;
233  }
234 
235  m = strlen(s);
236  n = strlen(DLL_EXT);
237 
238  // append library extension
239  if( (DLL_EXT != NULL) && ((m <= n) || strncasecmp(s+m-n, DLL_EXT, n)) )
240  {
241  t = NEWSTR(m+n);
242  sprintf(t, "%s%s", s, DLL_EXT);
243  delete(s);
244  }
245  else
246  {
247  t = s;
248  }
249 
250  return t;
251 }
252 
253 /*!
254  * \brief Dynamically load bsProxy server compatible interface module library.
255  *
256  * If the module path name is absolute, the only library at that location is
257  * attempted to be loaded. Otherwise, a series of path locations are searched for
258  * the library.
259  *
260  * \note The dlopen() and dlclose() functions only load/unload when a library
261  * iff the internal reference count is zero. However, bsProxy also needs to track
262  * the reference count, which the dl interface does not provide access to.
263  *
264  * \param sModUri Expanded, canonical name of the interface module.
265  *
266  * \return
267  * On success, returns DLL handle.\n
268  * On failure, returns NULL.
269  */
270 static void *ModDllOpen(const char *sModUri)
271 {
272  DListStrIter_T iter; ///< paths dlist iterator
273  char *sPath; ///< a dll path
274  char *sFqPath; ///< fully qualified path name
275  void *dllHandle = NULL; ///< loaded dll handle
276 
277  if( sModUri == NULL )
278  {
279  return NULL;
280  }
281 
282  // clear any existing error
283  dlerror();
284 
285  //
286  // Module path name is an absolute path. No search is made, simply let
287  // dlopen() do the work.
288  //
289  if( PathIsAbsolute(sModUri) )
290  {
291  if( (sFqPath = NewRealPath(sModUri)) != NULL )
292  {
293  LOGDIAG3("%s: trying dlopen(\"%s\").", ServerHasName(), sFqPath);
294  dllHandle = dlopen(sFqPath, RTLD_LAZY | RTLD_GLOBAL);
295  delete(sFqPath);
296  }
297  }
298 
299  //
300  // Search list of paths for the module's location and load.
301  //
302  else
303  {
304  for(sPath=DListStrIterDataFirst(BsModDllPaths, &iter), dllHandle=NULL;
305  sPath!=NULL && dllHandle==NULL;
306  sPath=DListStrIterDataNext(&iter))
307  {
308  if( (sFqPath = NewJoinedPath(sPath, sModUri)) != NULL )
309  {
310  LOGDIAG3("%s: trying dlopen(\"%s\").", ServerHasName(), sFqPath);
311  dllHandle = dlopen(sFqPath, RTLD_LAZY | RTLD_GLOBAL);
312  delete(sFqPath);
313  }
314  }
315 
316  //
317  // Use dlopen() default search.
318  //
319  if( dllHandle == NULL )
320  {
321  LOGDIAG3("%s: trying dlopen(\"%s\").", ServerHasName(), sModUri);
322  dllHandle = dlopen(sModUri, RTLD_LAZY | RTLD_GLOBAL);
323  }
324  }
325 
326  if( dllHandle == NULL )
327  {
328  BSPROXY_MOD_LOG_ERROR(sModUri, BS_ECODE_NO_MOD, "%s.", dlerror());
329  }
330 
331  return dllHandle;
332 }
333 
334 /*!
335  * \brief Unload the dynamic library from the application.
336  *
337  * \note The dlopen() and dlclose() functions only load/unload when a library
338  * iff the internal reference count is zero. However, bsProxy also needs to track
339  * the reference count, which the dl interface does not provide access to.
340  *
341  * \param sModUri Expanded, canonical name of the interface module.
342  * \param dllHandle DLL handle.
343  */
344 static void ModDllClose(const char *sModUri, void *dllHandle)
345 {
346  // clear any existing error
347  dlerror();
348 
349  if( dlclose(dllHandle) != 0 )
350  {
351  BSPROXY_MOD_LOG_ERROR(sModUri, BS_ECODE_NO_EXEC, "%s.", dlerror());
352  }
353 }
354 
355 /*!
356  * \brief Get the address of where the module symbol is loaded into memory.
357  *
358  * \param pModIF Exported module interface.
359  * \param sSym Symbol name.
360  *
361  * \return
362  * On success, returns the symbol address.\n
363  * On failure, NULL is returned.
364  */
365 static void *ModDllSym(BsProxyModIF_T *pModIF, const char *sSym)
366 {
367  void *pSym;
368  char *sEMsg;
369 
370  // clear any existing error
371  dlerror();
372 
373  // get symbol address
374  pSym = dlsym(pModIF->m_dllHandle, sSym);
375 
376  // error
377  if( pSym == NULL )
378  {
379  sEMsg = dlerror();
380  if( sEMsg == NULL )
381  {
382  sEMsg = "Not defined";
383  }
385  "%s: %s.", sSym, sEMsg);
386  }
387 
388  return pSym;
389 }
390 
391 /*!
392  * \brief Delete module interface block.
393  *
394  * \param pModIF Exported module interface.
395  */
396 static void ModDllDeleteIF(BsProxyModIF_T *pModIF)
397 {
398  if( pModIF != NULL )
399  {
400  delete((char *)pModIF->m_sModUri);
401  delete(pModIF);
402  }
403 }
404 
405 /*!
406  * \brief Allocate an attached exported module interface block.
407  *
408  * \note dlsym() can return NULL with no errors if the symbol's value is NULL.
409  * Checking the dlerror() return is the safe way to determine if an error has
410  * occurred. However, a bsProxy compatible module's exported interface is
411  * required to be defined.
412  *
413  * \param sModUri Expanded, canonical name of the interface module.
414  * \param dllHandle DLL handle.
415  *
416  * \return
417  * On success, returns a pointer to the module's exported interface.\n
418  * On failure, returns NULL.
419  */
420 static BsProxyModIF_T *ModDllNewIF(const char *sModUri, void *dllHandle)
421 {
422  BsProxyModIF_T *pModIF = NEW(BsProxyModIF_T);
423  int rc = BS_OK;
424 
425  pModIF->m_sModUri = new_strdup(sModUri); // self reference
426  pModIF->m_dllHandle = dllHandle; // opaque dll handle
427  pModIF->m_uRefCnt = 1; // module reference count
428 
429  //
430  // Init
431  //
433 
434  if( pModIF->m_fnModInit == NULL )
435  {
436  rc = -BS_ECODE_BAD_MOD;
437  }
438 
439  //
440  // Exit
441  //
443 
444  if( pModIF->m_fnModExit == NULL )
445  {
446  rc = -BS_ECODE_BAD_MOD;
447  }
448 
449  //
450  // Open
451  //
453 
454  if( pModIF->m_fnModOpen == NULL )
455  {
456  rc = -BS_ECODE_BAD_MOD;
457  }
458 
459  //
460  // Close
461  //
463 
464  if( pModIF->m_fnModClose == NULL )
465  {
466  rc = -BS_ECODE_BAD_MOD;
467  }
468 
469 
470  //
471  // Request
472  //
473  pModIF->m_fnModRequest = (BsModRequestFunc_P)ModDllSym(pModIF,
475 
476  if( pModIF->m_fnModRequest == NULL )
477  {
478  rc = -BS_ECODE_BAD_MOD;
479  }
480 
481  //
482  // Trace
483  //
485 
486  if( pModIF->m_fnModTrace == NULL )
487  {
488  rc = -BS_ECODE_BAD_MOD;
489  }
490 
491  //
492  // Info
493  //
495 
496  if( pModIF->m_fnModInfo == NULL )
497  {
498  rc = -BS_ECODE_BAD_MOD;
499  }
500 
501  // Error clean up.
502  if( rc < 0 )
503  {
504  ModDllDeleteIF(pModIF);
505  pModIF = NULL;
506  }
507 
508  return pModIF;
509 }
510 
511 
512 //.............................................................................
513 // I/F Module Hashing Functions
514 //.............................................................................
515 
516 /*!
517  * \brief Delete hash node data callback.
518  *
519  * Both the key and value are dynamically allocated.
520  *
521  * \param sModUri Interface module hash table key.
522  * \param pModIF Interface module hash table value.
523  */
524 static void ModHashDeleteData(void *sModUri, void *pModIF)
525 {
526  delete(sModUri);
527  ModDllDeleteIF((BsProxyModIF_T *)pModIF);
528 }
529 
530 /*!
531  * \brief Add the module data to the i/f module hash table.
532  *
533  * \param sModUri Allocated interface module hash table key.
534  * \param pModIF Allocated interface module hash table value.
535  *
536  * \copydoc doc_return_std
537  */
538 static int ModHashAdd(const char *sModUri, BsProxyModIF_T *pModIF)
539 {
540  char *sKey = new_strdup(sModUri);
541 
542  // insert into hash table, automatically allocating hnode_t
543  if( !hash_insert(BsModHashTbl, sKey, pModIF) )
544  {
545  LOGERROR("hash_insert(%s,...) failed", sKey);
546  ModHashDeleteData(sKey, pModIF);
547  return -BS_ECODE_NO_RSRC;
548  }
549 
550  return BS_OK;
551 }
552 
553 /*!
554  * \brief Remove and delete the module data from the i/f module hash table.
555  *
556  * \param pModIF Allocated interface module hash table value.
557  *
558  * \copydoc doc_return_std
559  */
560 static void ModHashDelete(BsProxyModIF_T *pModIF)
561 {
562  hnode_t *pNode;
563 
564  if( pModIF == NULL )
565  {
566  return;
567  }
568  else if( (pNode = hash_lookup(BsModHashTbl, pModIF->m_sModUri)) != NULL )
569  {
570  hash_node_delete(BsModHashTbl, pNode);
571  }
572 }
573 
574 /*!
575  * \brief Get the interface module's i/f from the module hash table.
576  *
577  * \param sModUri Interface module hash table key.
578  *
579  * \return
580  * On success, returns pointer to the module's exported interface.\n
581  * On failure, returns NULL.
582  */
583 static BsProxyModIF_T *ModHashGetIF(const char *sModUri)
584 {
585  hnode_t *pNode;
586 
587  if( (pNode = hash_lookup(BsModHashTbl, sModUri)) == NULL )
588  {
589  return NULL;
590  }
591  else
592  {
593  return (BsProxyModIF_T *)hnode_get(pNode);
594  }
595 }
596 
597 
598 // ---------------------------------------------------------------------------
599 // Interface Module to bsProxy Server Callback Interface
600 // ---------------------------------------------------------------------------
601 
602 /*!
603  * \brief Send module-specific repsonse callback function.
604  *
605  * \note Service thread request handler has already locked the virtual
606  * connection.
607  *
608  * \param hndVConn Virtual connection handle.
609  * \param uTid Request-Response transaction id.
610  * \param uMsgId Response message id.
611  * \param bufRsp Packed repsonse message body.
612  * \param uRspLen Length of response in buffer (number of bytes).
613  */
615  BsTid_T uTid,
616  BsMsgId_T uMsgId,
617  byte_t bufRsp[],
618  size_t uRspLen)
619 {
620  BsProxyVConn_T *pVConn;
621 
622  if( (pVConn = VConnGet(hndVConn)) != NULL )
623  {
624  ClientSendRsp(pVConn->m_hndClient, hndVConn, uTid, uMsgId, bufRsp, uRspLen);
625  }
626  else
627  {
628  LOGERROR("%s: %s(ecode=%d): VConn=%d.",
630  hndVConn);
631  }
632 }
633 
634 /*!
635  * \brief Send generic ok repsonse callback function.
636  *
637  * \note Service thread request handler has already locked the virtual
638  * connection.
639  *
640  * \param hndVConn Virtual connection handle.
641  * \param uTid Request-Response transaction id.
642  */
643 void ModCbSendOkRsp(BsVConnHnd_T hndVConn, BsTid_T uTid)
644 {
645  BsProxyVConn_T *pVConn;
646 
647  if( (pVConn = VConnGet(hndVConn)) != NULL )
648  {
649  ClientSendOkRsp(pVConn->m_hndClient, uTid);
650  }
651  else
652  {
653  LOGERROR("%s: %s(ecode=%d): VConn=%d.",
655  hndVConn);
656  }
657 }
658 
659 /*!
660  * \brief Send generic error repsonse callback function.
661  *
662  * \note Service thread request handler has already locked the virtual
663  * connection.
664  *
665  * \param hndVConn Virtual connection handle.
666  * \param uTid Request-Response transaction id.
667  * \param nECode \copydoc doc_param_ecode
668  * \param sErrFmt Error format string.
669  * \param ... Format string variable arguments.
670  */
672  BsTid_T uTid,
673  int nECode,
674  const char *sErrFmt,
675  ...)
676 {
677  BsProxyVConn_T *pVConn;
678  va_list ap;
679 
680  if( (pVConn = VConnGet(hndVConn)) != NULL )
681  {
682  va_start(ap, sErrFmt);
683  ClientSendVErrorRsp(pVConn->m_hndClient, uTid, nECode, sErrFmt, ap);
684  va_end(ap);
685  }
686  else
687  {
688  LOGERROR("%s: %s(ecode=%d): VConn=%d.",
690  hndVConn);
691  }
692 }
693 
694 /*!
695  * \brief Allocatae a new module resource table of fixed size.
696  *
697  * The resource table is indexed by the virtual connection handle.
698  *
699  * \param nMaxResources Maximum number of simultaneous resources supported.
700  *
701  * \return Pointer to allocated resource block.
702  */
703 BsModRsrcTbl_T *ModCbRsrcTblNew(int nMaxResources)
704 {
705  BsModRsrcTbl_T *pRsrcTbl = NEW(BsModRsrcTbl_T);
706 
707  pRsrcTbl->m_vecRsrc = new(sizeof(void *) * (size_t)nMaxResources);
708 
709  memset(pRsrcTbl->m_vecIndex, BSPROXY_VCONN_UNDEF,
710  sizeof(pRsrcTbl->m_vecIndex));
711 
712  pRsrcTbl->m_uMaxResources = (uint_t)nMaxResources;
713  pRsrcTbl->m_uInUseCount = 0;
714 
715  return pRsrcTbl;
716 }
717 
718 /*!
719  * \brief Delete an allocated resource table.
720  *
721  * \warning Module-specific resources should be freed up prior to calling this
722  * function.
723  *
724  * \param pRsrcTbl Pointer to resource table.
725  */
727 {
728  if( pRsrcTbl != NULL )
729  {
730  delete(pRsrcTbl->m_vecRsrc);
731  delete(pRsrcTbl);
732  }
733 }
734 
735 /*!
736  * \brief Add a new resource to the resource table.
737  *
738  * \param pRsrcTbl Pointer to resource table.
739  * \param hndVConn Virtual connection handle.
740  * \param pRsrc Pointer to allocated resource associated with handle.
741  *
742  * \copydoc doc_return_std
743  */
744 int ModCbRsrcAdd(BsModRsrcTbl_T *pRsrcTbl, BsVConnHnd_T hndVConn, void *pRsrc)
745 {
746  int index;
747 
748  // bad handle
749  if( !BSMOD_IS_VCONN_HANDLE(hndVConn) )
750  {
751  return -BS_ECODE_BAD_VCONN_HND;
752  }
753 
754  // no more resources available
755  else if( pRsrcTbl->m_uInUseCount >= pRsrcTbl->m_uMaxResources )
756  {
757  return -BS_ECODE_NO_RSRC;
758  }
759 
760  // find empty slot in resource table
761  for(index=0; index<pRsrcTbl->m_uMaxResources; ++index)
762  {
763  if( pRsrcTbl->m_vecRsrc[index] == NULL )
764  {
765  break;
766  }
767  }
768 
769  // internal error - log these
770  if( (uint_t)index >= pRsrcTbl->m_uMaxResources )
771  {
772  LOGERROR("Internal module data corruption.");
773  return -BS_ECODE_INTERNAL;
774  }
775 
776  // add resource to resource table
777  pRsrcTbl->m_vecRsrc[index] = pRsrc;
778  pRsrcTbl->m_vecIndex[hndVConn] = (byte_t)index;
779  pRsrcTbl->m_uInUseCount++;
780 
781  return index;
782 }
783 
784 /*!
785  * \brief Remove a resource from the resource table.
786  *
787  * The resource is not deleted.
788  *
789  * \param pRsrcTbl Pointer to resource table.
790  * \param hndVConn Virtual connection handle.
791  *
792  * \return On success, returns pointer to removed resource. On failure, NULL
793  * is returned.
794  */
795 void *ModCbRsrcRemove(BsModRsrcTbl_T *pRsrcTbl, BsVConnHnd_T hndVConn)
796 {
797  int index;
798  void *pRsrc;
799 
800  // bad handle
801  if( !BSMOD_IS_VCONN_HANDLE(hndVConn) )
802  {
803  return NULL;
804  }
805 
806  // get resource index
807  else if( (index = BSMOD_RSRC_INDEX(pRsrcTbl, hndVConn)) < 0 )
808  {
809  return NULL;
810  }
811 
812  // removed resource
813  pRsrc = pRsrcTbl->m_vecRsrc[index];
814 
815  // remove resource to resource table
816  pRsrcTbl->m_vecRsrc[index] = NULL;
817  pRsrcTbl->m_vecIndex[hndVConn] = (byte_t)BSPROXY_VCONN_UNDEF;
818  pRsrcTbl->m_uInUseCount--;
819 
820  return pRsrc;
821 }
822 
823 /*!
824  * \brief Copy the device URI associated with the virtual connection.
825  *
826  * \param hndVConn Virtual connection handle.
827  * \param [out] dest Destination buffer.
828  * \param n Size of buffer.
829  *
830  * \return Pointer to destination buffer dest.
831  */
832 const char *ModCbGetDevUri(BsVConnHnd_T hndVConn, char dest[], size_t n)
833 {
834  BsProxyVConn_T *pVConn;
835 
836  if( (pVConn = VConnAcquire(hndVConn)) != NULL )
837  {
838  strncpy(dest, pVConn->m_pThCtl->m_sDevUri, n);
839  dest[n-1] = 0;
840  VConnRelease(hndVConn);
841  }
842  else
843  {
844  dest[0] = 0;
845  }
846 
847  return dest;
848 }
849 
850 /*!
851  * \brief Delete the module iterator.
852  *
853  * \param pIter Module iterator.
854  */
856 {
857  if( pIter != NULL )
858  {
859  delete(pIter->m_sDevUri);
860  delete(pIter->m_sModUri);
861  delete(pIter);
862  }
863 }
864 
865 /*!
866  * \brief Get the next set of information given the iterator state.
867  *
868  * If a virtual connection match is found, an iterator data is updated.
869  *
870  * If no match is found, the iterator is auto-deleted.
871  *
872  * \param pIter Initialized, allocated iterator.
873  *
874  * \return On success, returns the pointer to the iterator.\n
875  * On failure, NULL is returned.
876  */
878 {
879  BsVConnHnd_T hndVConn;
880  BsProxyVConn_T *pVConn;
881  bool_t bHasMatch = false;
882 
883  if( pIter == NULL )
884  {
885  return NULL;
886  }
887 
888  for(hndVConn=pIter->m_hndVConn+1;
889  (pIter!=NULL) && (hndVConn<BSPROXY_VCONN_NUMOF);
890  ++hndVConn)
891  {
892  if( (pVConn = VConnAcquire(hndVConn)) != NULL )
893  {
894  switch( pIter->m_eOver )
895  {
896  case BsModIterOverDevUri:
897  if( !strcmp(pVConn->m_pThCtl->m_sDevUri, pIter->m_sDevUri) )
898  {
899  pIter->m_hndVConn = hndVConn;
900  delete(pIter->m_sModUri);
901  pIter->m_sModUri = new_strdup(pVConn->m_pModIF->m_sModUri);
902  pIter->m_rd = pVConn->m_rd;
903  bHasMatch = true;
904  }
905  break;
906  case BsModIterOverModUri:
907  if( !strcmp(pVConn->m_pModIF->m_sModUri, pIter->m_sModUri) )
908  {
909  pIter->m_hndVConn = hndVConn;
910  delete(pIter->m_sDevUri);
911  pIter->m_sDevUri = new_strdup(pVConn->m_pThCtl->m_sDevUri);
912  pIter->m_rd = pVConn->m_rd;
913  bHasMatch = true;
914  }
915  break;
916  case BsModIterOverVConn:
917  pIter->m_hndVConn = hndVConn;
918  delete(pIter->m_sDevUri);
919  pIter->m_sDevUri = new_strdup(pVConn->m_pThCtl->m_sDevUri);
920  delete(pIter->m_sModUri);
921  pIter->m_sModUri = new_strdup(pVConn->m_pModIF->m_sModUri);
922  pIter->m_rd = pVConn->m_rd;
923  bHasMatch = true;
924  break;
925  default:
926  ModCbIterDelete(pIter);
927  pIter = NULL;
928  break;
929  }
930  VConnRelease(hndVConn);
931  }
932  }
933 
934  if( !bHasMatch )
935  {
936  ModCbIterDelete(pIter);
937  pIter = NULL;
938  }
939 
940  return pIter;
941 }
942 
943 /*!
944  * \brief Start an iterator over the virtual connections matching the given
945  * pattern.
946  *
947  * If a virtual connection match is found, an iterator is allocated and its data
948  * is filled with the first set of information.
949  *
950  * The caller must delete the iterator by calling \ref ModCbIterNext() until
951  * there are no more matches (auto-delete) or by calling \ref ModCbIterDelete().
952  *
953  * \param eOver What pattern to iterator over (see \ref BsModIterOver_T).
954  * \param sPattern Device or module URI pattern string.
955  *
956  * \return On success, returns the pointer to the allocacted module iterator.\n
957  * On failure, NULL is returned.
958  */
959 BsModIter_T *ModCbIterFirst(BsModIterOver_T eOver, const char *sPattern)
960 {
961  BsModIter_T *pIter = NEW(BsModIter_T);
962 
963  pIter->m_eOver = eOver;
964  pIter->m_hndVConn = -1;
965  pIter->m_sDevUri = NULL;
966  pIter->m_sModUri = NULL;
967  pIter->m_rd = -1;
968 
969  switch( eOver )
970  {
971  case BsModIterOverDevUri:
972  pIter->m_sDevUri = new_strdup(sPattern);
973  return ModCbIterNext(pIter);
974  case BsModIterOverModUri:
975  pIter->m_sModUri = new_strdup(sPattern);
976  return ModCbIterNext(pIter);
977  case BsModIterOverVConn:
978  return ModCbIterNext(pIter);
979  default:
980  ModCbIterDelete(pIter);
981  return NULL;
982  }
983 }
984 
985 /*!
986  * \brief Interface module callbacks to bsProxy server services.
987  */
989 {
990  ModCbSendRsp, ///< send module-specific response
991  ModCbSendOkRsp, ///< send standard ok response
992  ModCbSendErrorRsp, ///< send standard error response
993  ModCbRsrcTblNew, ///< new resource table
994  ModCbRsrcTblDelete, ///< delete resource table
995  ModCbRsrcAdd, ///< add a new resource
996  ModCbRsrcRemove, ///< remove a resource
997  ModCbGetDevUri, ///< get virtual connection's device URI
998  ModCbIterFirst, ///< start module iterator over virtual connections
999  ModCbIterNext, ///< get next module iteration instance
1000  ModCbIterDelete ///< delete module iterator
1001 };
1002 
1003 
1004 // ---------------------------------------------------------------------------
1005 // Public Interface
1006 // ---------------------------------------------------------------------------
1007 
1008 /*!
1009  * \brief The bsProxy interface module handling one-time initialization.
1010  *
1011  * \param pDListLibPath List of optional library search paths.
1012  */
1013 void ModOneTimeInit(DListStr_T *pDListLibPath)
1014 {
1015  // create mutex
1016  pthread_mutex_init(&BsModMutex, NULL);
1017 
1018  BsModHashTbl = hash_table_create(
1019  true, // dynamic table sizing
1020  (hashcount_t)BSPROXY_MOD_HASH_MIN, // minimum size
1021  (hashcount_t)BSPROXY_MOD_HASH_MAX, // maximum size
1022  NULL, // use default comparator function
1023  NULL, // use default hashing function
1024  ModHashDeleteData); // hash node data deletion function
1025 
1026  // turn off most asserts()
1027  hash_set_self_verify(false);
1028 
1029  // initialize DLL environment
1030  ModDllInit(pDListLibPath);
1031 }
1032 
1033 /*!
1034  * \brief Convert the module name to a quasi Uniform Resource Id.
1035  *
1036  * \param sModName Module path name.
1037  *
1038  * \return
1039  * On success, an allocated, canonical library path name is returned.\n
1040  * On failure, NULL is returned.
1041  */
1042 char *ModNewModUri(const char *sModName)
1043 {
1044  return ModDllNewCanonicalName(sModName);
1045 }
1046 
1047 /*!
1048  * \brief Get the defined interface from a previously loaded i/f module.
1049  *
1050  * Multi-Thread safe.
1051  *
1052  * \param sModUri Interface module expanded, canonical name.
1053  *
1054  * \return
1055  * On success, returns a pointer to the module's exported interface.\n
1056  * Returns NULL if no interface is found.
1057  */
1058 BsProxyModIF_T *ModGetLoadedIF(const char *sModUri)
1059 {
1060  BsProxyModIF_T *pModIF;
1061 
1062  ModLock();
1063 
1064  pModIF = ModHashGetIF(sModUri);
1065 
1066  ModUnlock();
1067 
1068  return pModIF;
1069 }
1070 
1071 /*!
1072  * \brief Load the interface module.
1073  *
1074  * The module's expanded, canonical name is determined, the dynamic library is
1075  * loaded, the module's exported interface is attached, and the module's
1076  * initialization routine is called.
1077  *
1078  * The the same module is loaded again, the reference count is bumped and the
1079  * already attached interface is returned.
1080  *
1081  * Multi-Thread safe.
1082  *
1083  * \param sModUri Interface module expanded, canonical name.
1084  *
1085  * \return
1086  * On success, returns a pointer to the module's exported interface.\n
1087  * On failure, returns NULL.
1088  */
1089 BsProxyModIF_T *ModLoad(const char *sModUri)
1090 {
1091  BsProxyModIF_T *pModIF = NULL;
1092  void *dllHandle = NULL;
1093  int rc;
1094 
1095  // lock global mutex
1096  ModLock();
1097 
1098  //
1099  // Check if module is already loaded.
1100  //
1101  if( (pModIF = ModHashGetIF(sModUri)) != NULL )
1102  {
1103  rc = BS_OK;
1104  pModIF->m_uRefCnt++;
1105  LOGDIAG1("Interface Module \"%s\" attached (refcnt=%u).",
1106  pModIF->m_sModUri, pModIF->m_uRefCnt);
1107  }
1108 
1109  //
1110  // Load the dynamic library.
1111  //
1112  else if( (dllHandle = ModDllOpen(sModUri)) == NULL )
1113  {
1114  rc = -BS_ECODE_NO_MOD;
1115  BSPROXY_MOD_LOG_ERROR(sModUri, rc, "Failed to open.");
1116  }
1117 
1118  //
1119  // Allocate new interface control blcok and attach module's exported
1120  // interface.
1121  //
1122  else if( (pModIF = ModDllNewIF(sModUri, dllHandle)) == NULL )
1123  {
1124  rc = -BS_ECODE_BAD_MOD;
1125  BSPROXY_MOD_LOG_ERROR(sModUri, rc, "Failed to get interface.");
1126  }
1127 
1128  //
1129  // Call the newly loaded module's exported initialization function to
1130  // initialize any module specific data and resources.
1131  //
1132  else if( (rc = pModIF->m_fnModInit(sModUri, &BsModProxyCallbacks)) < 0 )
1133  {
1134  rc = -BS_ECODE_BAD_MOD;
1135  BSPROXY_MOD_LOG_ERROR(sModUri, rc, "Failed to initialize.");
1136  }
1137 
1138  //
1139  // Add the module to the hash table (failure auto-deletes node data).
1140  //
1141  else if( (rc = ModHashAdd(sModUri, pModIF)) < 0 )
1142  {
1143  rc = -BS_ECODE_NO_RSRC;
1144  BSPROXY_MOD_LOG_ERROR(sModUri, rc, "Failed to add module to hash table.");
1145  }
1146 
1147  //
1148  // Successfully loaded new module.
1149  //
1150  else
1151  {
1152  rc = BS_OK;
1153  LOGDIAG1("Interface Module \"%s\" loaded (refcnt=%u).",
1154  pModIF->m_sModUri, pModIF->m_uRefCnt);
1155  }
1156 
1157  ModUnlock();
1158 
1159  //
1160  // Error clean up.
1161  //
1162  if( rc < 0 )
1163  {
1164  if( dllHandle != NULL )
1165  {
1166  dlclose(dllHandle);
1167  dllHandle = NULL;
1168  }
1169 
1170  if( pModIF != NULL )
1171  {
1172  ModDllDeleteIF(pModIF);
1173  pModIF = NULL;
1174  }
1175  }
1176 
1177  return pModIF;
1178 }
1179 
1180 /*!
1181  * \brief Unload the interface module.
1182  *
1183  * The module's reference count is decremented. If the count is zero, then the
1184  * module's exit routine is called and the module dynamic library is unloaded
1185  * from bsProxy server application.
1186  *
1187  * Multi-Thread safe.
1188  *
1189  * \param pModIF Exported module interface.
1190  */
1192 {
1193 
1194  ModLock();
1195 
1196  if( (pModIF = ModHashGetIF(pModIF->m_sModUri)) != NULL )
1197  {
1198  if( pModIF->m_uRefCnt > 0 )
1199  {
1200  pModIF->m_uRefCnt--;
1201  }
1202 
1203  if( pModIF->m_uRefCnt == 0 )
1204  {
1205  // call module specific exported exit function
1206  pModIF->m_fnModExit();
1207 
1208  // unload the dll
1209  ModDllClose(pModIF->m_sModUri, pModIF->m_dllHandle);
1210 
1211  LOGDIAG1("Interface Module \"%s\" unloaded (refcnt=%u).",
1212  pModIF->m_sModUri, pModIF->m_uRefCnt);
1213 
1214  // delete data
1215  ModHashDelete(pModIF);
1216  }
1217  else
1218  {
1219  LOGDIAG1("Interface Module \"%s\" detached (refcnt=%u).",
1220  pModIF->m_sModUri, pModIF->m_uRefCnt);
1221  }
1222  }
1223 
1224  ModUnlock();
1225 }
uint_t BsMsgId_T
client message id type [0-64k].
Definition: BotSense.h:188
void ModCbSendRsp(BsVConnHnd_T hndVConn, BsTid_T uTid, BsMsgId_T uMsgId, byte_t bufRsp[], size_t uRspLen)
Send module-specific repsonse callback function.
Definition: bsProxyMod.c:614
iterator over virtual connections (no pattern)
Definition: bsProxyModIF.h:217
#define BSMOD_SYM_OPEN_S
open function string
Definition: bsProxyModIF.h:105
BsModTraceFunc_T * BsModTraceFunc_P
pointer to msg trace func.
Definition: bsProxyModIF.h:612
BsModExitFunc_P m_fnModExit
module exit
Definition: bsProxy.h:126
<b><i>BotSense</i></b> bsProxy IP server declarations.
Useful indirect indexing of handle to resource instance structure.
Definition: bsProxyModIF.h:136
int m_rd
module resource descriptor
Definition: bsProxy.h:227
BotSense client application - bsProxy server-terminated core messages.
char * ModNewModUri(const char *sModName)
Convert the module name to a quasi Uniform Resource Id.
Definition: bsProxyMod.c:1042
#define BSPROXY_MOD_HASH_MAX
maximum hash table size
Definition: bsProxyMod.c:93
void ModCbSendErrorRsp(BsVConnHnd_T hndVConn, BsTid_T uTid, int nECode, const char *sErrFmt,...)
Send generic error repsonse callback function.
Definition: bsProxyMod.c:671
void VConnRelease(BsVConnHnd_T hndVConn)
Release the locked virtual client.
Definition: bsProxyVConn.c:585
const char * ModCbGetDevUri(BsVConnHnd_T hndVConn, char dest[], size_t n)
Copy the device URI associated with the virtual connection.
Definition: bsProxyMod.c:832
BsModRequestFunc_T * BsModRequestFunc_P
pointer to request func.
Definition: bsProxyModIF.h:601
BsModCloseFunc_T * BsModCloseFunc_P
pointer to close function
Definition: bsProxyModIF.h:581
static char * ModDllNewCanonicalName(const char *sModName)
Make DLL canonical file name.
Definition: bsProxyMod.c:222
#define BS_PLUGIN_DIR
bsProxy module plugin subdirectory
Definition: bsProxyMod.c:89
uint_t BsTid_T
client transaction id type [0-255].
Definition: BotSense.h:172
#define BSPROXY_VCONN_NUMOF
total number of module handles
Definition: BotSense.h:144
#define BSPROXY_MOD_HASH_MIN
minimum hash table size
Definition: bsProxyMod.c:92
uint_t m_uInUseCount
resources in-use count
Definition: bsProxyModIF.h:141
static bool_t ModTryLock()
Try to lock module&#39;s global mutual exclusion.
Definition: bsProxyMod.c:153
BsModInfoFunc_T * BsModInfoFunc_P
pointer to mod info function
Definition: bsProxyModIF.h:621
BsProxyThCtl_T * m_pThCtl
service thread
Definition: bsProxy.h:225
BsProxyModIF_T * ModLoad(const char *sModUri)
Load the interface module.
Definition: bsProxyMod.c:1089
BsModIter_T * ModCbIterNext(BsModIter_T *pIter)
Get the next set of information given the iterator state.
Definition: bsProxyMod.c:877
static void * ModDllSym(BsProxyModIF_T *pModIF, const char *sSym)
Get the address of where the module symbol is loaded into memory.
Definition: bsProxyMod.c:365
static void ModUnlock()
Unlock module&#39;s global mutual exclusion.
Definition: bsProxyMod.c:135
static hash_t * BsModHashTbl
i/f module hash table
Definition: bsProxyMod.c:96
byte_t m_vecIndex[BSPROXY_VCONN_MOD_NUMOF]
vecIndex[handle] -> index
Definition: bsProxyModIF.h:138
#define BSMOD_IS_VCONN_HANDLE(hndVConn)
Test if the handle is in the valid module virtual connection range.
Definition: bsProxyModIF.h:149
void ModUnload(BsProxyModIF_T *pModIF)
Unload the interface module.
Definition: bsProxyMod.c:1191
static void ModDllInit(DListStr_T *pDListLibPath)
Definition: bsProxyMod.c:175
BsModExitFunc_T * BsModExitFunc_P
pointer to exit function
Definition: bsProxyModIF.h:541
#define BSMOD_SYM_TRACE_S
tracing func string
Definition: bsProxyModIF.h:108
#define BS_AUX_LIBDIR
additional bsProxy library directory
Definition: bsProxyMod.c:85
static void ModDllClose(const char *sModUri, void *dllHandle)
Unload the dynamic library from the application.
Definition: bsProxyMod.c:344
INLINE_IN_H const char * ServerHasName()
Get the <b><i>BotSense</i></b> server&#39;s official name.
Definition: bsProxy.h:485
#define BS_OK
not an error, success
Definition: BotSense.h:66
static void ModHashDeleteData(void *sModUri, void *pModIF)
Delete hash node data callback.
Definition: bsProxyMod.c:524
#define BS_ECODE_BAD_VCONN_HND
bad virtual connection handle
Definition: BotSense.h:79
void ModCbRsrcTblDelete(BsModRsrcTbl_T *pRsrcTbl)
Delete an allocated resource table.
Definition: bsProxyMod.c:726
BsModCloseFunc_P m_fnModClose
device close
Definition: bsProxy.h:128
void * ModCbRsrcRemove(BsModRsrcTbl_T *pRsrcTbl, BsVConnHnd_T hndVConn)
Remove a resource from the resource table.
Definition: bsProxyMod.c:795
#define BSPROXY_VCONN_UNDEF
undefined virtual connection handle
Definition: BotSense.h:139
static BsProxyModIF_T * ModDllNewIF(const char *sModUri, void *dllHandle)
Allocate an attached exported module interface block.
Definition: bsProxyMod.c:420
static pthread_mutex_t BsModMutex
bsProxy module operations mutex
Definition: bsProxyMod.c:95
#define BS_ECODE_NO_EXEC
cannot execute
Definition: BotSense.h:88
BsModInfoFunc_P m_fnModInfo
static info
Definition: bsProxy.h:131
int ClientSendOkRsp(BsProxyClientHnd_T hndClient, BsTid_T uTid)
Send an ok response to the client.
Interface Module callbacks to bsProxy services type.
Definition: bsProxyModIF.h:235
BsModOpenFunc_T * BsModOpenFunc_P
pointer to open function
Definition: bsProxyModIF.h:568
int ModCbRsrcAdd(BsModRsrcTbl_T *pRsrcTbl, BsVConnHnd_T hndVConn, void *pRsrc)
Add a new resource to the resource table.
Definition: bsProxyMod.c:744
char * m_sDevUri
device URI
Definition: bsProxyModIF.h:227
BsProxyVConn_T * VConnAcquire(BsVConnHnd_T hndVConn)
Acquire virtual connection, locking it from other threads.
Definition: bsProxyVConn.c:552
#define BS_ECODE_BAD_MOD
bad interface module
Definition: BotSense.h:84
static BsModProxyCb_T BsModProxyCallbacks
Interface module callbacks to bsProxy server services.
Definition: bsProxyMod.c:988
iterator over device URI
Definition: bsProxyModIF.h:215
BsProxyClientHnd_T m_hndClient
proxied client handle
Definition: bsProxy.h:224
static int ModHashAdd(const char *sModUri, BsProxyModIF_T *pModIF)
Add the module data to the i/f module hash table.
Definition: bsProxyMod.c:538
BsModTraceFunc_P m_fnModTrace
tracing
Definition: bsProxy.h:130
#define BSMOD_SYM_EXIT_S
exit function string
Definition: bsProxyModIF.h:104
uint_t m_uMaxResources
maximum resource count
Definition: bsProxyModIF.h:140
#define BS_ECODE_NO_RSRC
no resource available
Definition: BotSense.h:85
int m_rd
module&#39;s resource descriptor
Definition: bsProxyModIF.h:229
static DListStr_T * BsModDllPaths
module search paths
Definition: bsProxyMod.c:97
BsProxyVConn_T * VConnGet(BsVConnHnd_T hndVConn)
Get the virtual connection entry associated with the handle.
Definition: bsProxyVConn.c:248
#define BSMOD_SYM_CLOSE_S
close function string
Definition: bsProxyModIF.h:106
static void ModHashDelete(BsProxyModIF_T *pModIF)
Remove and delete the module data from the i/f module hash table.
Definition: bsProxyMod.c:560
uint_t m_uRefCnt
vconn reference count for this module
Definition: bsProxy.h:124
#define BS_ECODE_NO_MOD
no interface module
Definition: BotSense.h:83
const char * m_sModUri
module Uniform Resource Id
Definition: bsProxy.h:122
<b><i>BotSense</i></b> bsProxy Dynamically Linked Library module interface.
BsModRsrcTbl_T * ModCbRsrcTblNew(int nMaxResources)
Allocatae a new module resource table of fixed size.
Definition: bsProxyMod.c:703
BsModInitFunc_P m_fnModInit
module init
Definition: bsProxy.h:125
void ModCbSendOkRsp(BsVConnHnd_T hndVConn, BsTid_T uTid)
Send generic ok repsonse callback function.
Definition: bsProxyMod.c:643
static BsProxyModIF_T * ModHashGetIF(const char *sModUri)
Get the interface module&#39;s i/f from the module hash table.
Definition: bsProxyMod.c:583
#define BSMOD_SYM_REQUEST_S
request func string
Definition: bsProxyModIF.h:107
BsVConnHnd_T m_hndVConn
virtual connection handle
Definition: bsProxyModIF.h:226
#define BSMOD_SYM_INFO_S
info function string
Definition: bsProxyModIF.h:109
#define BS_ECODE_INTERNAL
internal error (bug)
Definition: BotSense.h:93
int ClientSendVErrorRsp(BsProxyClientHnd_T hndClient, BsTid_T uTid, int nECode, const char *sErrFmt, va_list ap)
Send va_list error response to the client.
static void * ModDllOpen(const char *sModUri)
Dynamically load bsProxy server compatible interface module library.
Definition: bsProxyMod.c:270
#define BS_ECODE_NO_VCONN
virtual connection not found
Definition: BotSense.h:80
BsProxyModIF_T * ModGetLoadedIF(const char *sModUri)
Get the defined interface from a previously loaded i/f module.
Definition: bsProxyMod.c:1058
#define BSMOD_SYM_INIT_S
Required Module Symbols Strings.
Definition: bsProxyModIF.h:103
BsModIter_T * ModCbIterFirst(BsModIterOver_T eOver, const char *sPattern)
Start an iterator over the virtual connections matching the given pattern.
Definition: bsProxyMod.c:959
static void ModDllDeleteIF(BsProxyModIF_T *pModIF)
Delete module interface block.
Definition: bsProxyMod.c:396
Module Iterator Type.
Definition: bsProxyModIF.h:223
int ClientSendRsp(BsProxyClientHnd_T hndClient, BsVConnHnd_T hndVConn, BsTid_T uTid, BsMsgId_T uMsgId, byte_t bufRsp[], size_t uRspSize)
Send module-specific response to the client.
char * m_sModUri
module URI
Definition: bsProxyModIF.h:228
#define BSMOD_RSRC_INDEX(pRsrcTbl, hndVConn)
Get the resource index given the handle.
Definition: bsProxyModIF.h:181
#define BSPROXY_MOD_LOG_ERROR(moduri, ecode, efmt,...)
Log Proxy Server Module Error.
Definition: bsProxyMod.c:107
void ModCbIterDelete(BsModIter_T *pIter)
Delete the module iterator.
Definition: bsProxyMod.c:855
void ** m_vecRsrc
vecRsrc[index] -> rsrc
Definition: bsProxyModIF.h:139
iterator over module URI
Definition: bsProxyModIF.h:216
BsModOpenFunc_P m_fnModOpen
device open
Definition: bsProxy.h:127
#define DLL_EXT
standard dll library file name extension
Definition: bsProxyMod.c:79
BsModInitFunc_T * BsModInitFunc_P
pointer to init function
Definition: bsProxyModIF.h:530
const char * m_sDevUri
proxied device URI or server
Definition: bsProxy.h:150
BsModIterOver_T
What to iterate over.
Definition: bsProxyModIF.h:213
BsModIterOver_T m_eOver
iterator over enum
Definition: bsProxyModIF.h:225
BsProxyModIF_T * m_pModIF
interface module I/F
Definition: bsProxy.h:226
void * m_dllHandle
dynamic library loader handle
Definition: bsProxy.h:123
<b><i>BotSense</i></b> package top-level, unifying header declarations.
void ModOneTimeInit(DListStr_T *pDListLibPath)
The bsProxy interface module handling one-time initialization.
Definition: bsProxyMod.c:1013
int BsVConnHnd_T
virtual connection handle type
Definition: BotSense.h:151
static void ModLock()
Lock module&#39;s global mutual exclusion.
Definition: bsProxyMod.c:121
BsModRequestFunc_P m_fnModRequest
module request
Definition: bsProxy.h:129