/* * Hamlib Interface - provides registering for dynamically loadable backends. * Copyright (c) 2000,2001 by Stephane Fillod and Frank Singleton * * $Id: register.c,v 1.12 2001-12-16 20:02:12 fillods Exp $ * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include /* This is libtool's dl wrapper */ #include #include #ifndef PATH_MAX # define PATH_MAX 1024 #endif #define RIG_BACKEND_MAX 32 /* * RIG_BACKEND_LIST is defined in riglist.h, please keep it up to data, * ie. each time you give birth to a new backend * Also, it should be possible to register "external" backend, * that is backend that were not known by Hamlib at compile time. * Maybe, riglist.h should reserve some numbers for them? --SF */ static struct { int be_num; const char *be_name; rig_model_t (*be_probe)(port_t *); } rig_backend_list[RIG_BACKEND_MAX] = RIG_BACKEND_LIST; /* * This struct to keep track of known rig models. * It is chained, and used in a hash table, see below. */ struct rig_list { const struct rig_caps *caps; lt_dlhandle handle; /* handle returned by lt_dlopen() */ struct rig_list *next; }; #define RIGLSTHASHSZ 16 #define HASH_FUNC(a) ((a)%RIGLSTHASHSZ) /* * The rig_hash_table is a hash table pointing to a list of next==NULL * terminated caps. */ static struct rig_list *rig_hash_table[RIGLSTHASHSZ] = { NULL, }; static int rig_lookup_backend(rig_model_t rig_model); /* * Basically, this is a hash insert function that doesn't check for dup! */ int rig_register(const struct rig_caps *caps) { int hval; struct rig_list *p; if (!caps) return -RIG_EINVAL; rig_debug(RIG_DEBUG_VERBOSE, "rig_register (%d)\n",caps->rig_model); #ifndef DONT_WANT_DUP_CHECK if (rig_get_caps(caps->rig_model)!=NULL) return -RIG_EINVAL; #endif p = (struct rig_list*)malloc(sizeof(struct rig_list)); if (!p) return -RIG_ENOMEM; hval = HASH_FUNC(caps->rig_model); p->caps = caps; p->handle = NULL; p->next = rig_hash_table[hval]; rig_hash_table[hval] = p; return RIG_OK; } /* * Get rig capabilities. * ie. rig_hash_table lookup */ const struct rig_caps *rig_get_caps(rig_model_t rig_model) { struct rig_list *p; for (p = rig_hash_table[HASH_FUNC(rig_model)]; p; p=p->next) { if (p->caps->rig_model == rig_model) return p->caps; } return NULL; /* sorry, caps not registered! */ } /* * lookup for backend index in rig_backend_list table, * according to BACKEND_NUM * return -1 if not found. */ static int rig_lookup_backend(rig_model_t rig_model) { int i; for (i=0; inext) { if (p->caps->rig_model == rig_model) { if (q == NULL) rig_hash_table[hval] = p->next; else q->next = p->next; free(p); return RIG_OK; } q = p; } return -RIG_EINVAL; /* sorry, caps not registered! */ } /* * rig_list_foreach * executes cfunc on all the elements stored in the rig hash list */ int rig_list_foreach(int (*cfunc)(const struct rig_caps*, rig_ptr_t),rig_ptr_t data) { struct rig_list *p; int i; if (!cfunc) return -RIG_EINVAL; for (i=0; inext) if ((*cfunc)(p->caps,data) == 0) return RIG_OK; } return RIG_OK; } /* * rig_probe_all * called straight by rig_probe */ rig_model_t rig_probe_all(port_t *p) { int i; rig_model_t rig_model; for (i=0; i