/* * PBX: simulates a Private Branch Exchange. */ #include #include #include #include #include "pbx.h" #include "debug.h" /* * Initialize a new PBX. * * @return the newly initialized PBX, or NULL if initialization fails. */ #if 0 typedef struct pbx { pthread_mutex_t mutex; int exts[PBX_MAX_EXTENSIONS]; TU tus[PBX_MAX_EXTENSIONS]; } PBX; PBX *pbx_init() { PBX *pbx = malloc(sizeof(PBX)); if (!pbx) { debug("ERROR: Fail to alloc memeory for pbx") return NULL; } // init pbx memset(pbx, 0, sizeof(PBX)); pthread_mutex_init(&pbx->mutex, NULL); return pbx; } #endif /* * Shut down a pbx, shutting down all network connections, waiting for all server * threads to terminate, and freeing all associated resources. * If there are any registered extensions, the associated network connections are * shut down, which will cause the server threads to terminate. * Once all the server threads have terminated, any remaining resources associated * with the PBX are freed. The PBX object itself is freed, and should not be used again. * * @param pbx The PBX to be shut down. */ #if 0 void pbx_shutdown(PBX *pbx) { if (!pbx) { debug("ERROR: pbx does not extst"); return; } pthread_mutex_lock(&pbx->mutex); for (size_t i = 0; i < PBX_MAX_EXTENSIONS; i++) { int socket = pbx->exts[i]; if (socket) shutdown(socket, SHUT_RD); pbx->exts[i] = 0; } pthread_mutex_unlock(&pbx->mutex); pthread_mutex_destroy(&pbx->mutex); free(pbx); } #endif /* * Register a telephone unit with a PBX at a specified extension number. * This amounts to "plugging a telephone unit into the PBX". * The TU is initialized to the TU_ON_HOOK state. * The reference count of the TU is increased and the PBX retains this reference *for as long as the TU remains registered. * A notification of the assigned extension number is sent to the underlying network * client. * * @param pbx The PBX registry. * @param tu The TU to be registered. * @param ext The extension number on which the TU is to be registered. * @return 0 if registration succeeds, otherwise -1. */ #if 0 int pbx_register(PBX *pbx, TU *tu, int ext) { if (!pbx || !tu) { debug("ERROR: pbx or tu does not exist"); return -1; } if (ext > PBX_MAX_EXTENSIONS + 1 || ext < 1) { debug("ERROR: ext is out of range"); return -1; } pthread_mutex_lock(&pbx->mutex); if (pbx->exts[ext-1] != 0) { debug("ERROR: ext already exist"); pthread_mutex_unlock(&pbx->mutex); return -1; } tu_ref(tu, "Register tu to pbx"); tu_set_extension(tu, ext); pbx->exts[ext-1] = ext; pthread_mutex_unlock(&pbx->mutex); return 0; } #endif /* * Unregister a TU from a PBX. * This amounts to "unplugging a telephone unit from the PBX". * The TU is disassociated from its extension number. * Then a hangup operation is performed on the TU to cancel any * call that might be in progress. * Finally, the reference held by the PBX to the TU is released. * * @param pbx The PBX. * @param tu The TU to be unregistered. * @return 0 if unregistration succeeds, otherwise -1. */ #if 0 int pbx_unregister(PBX *pbx, TU *tu) { if (!pbx || !tu) { debug("ERROR: pbx or tu does not exist"); return -1; } int ext = tu_extension(tu); if (ext > PBX_MAX_EXTENSIONS + 1 || ext < 1) { debug("ERROR: ext is out of range"); return -1; } pthread_mutex_lock(&pbx->mutex); if (pbx->exts[ext-1] == 0) { debug("ERROR: ext does not exist"); pthread_mutex_unlock(&pbx->mutex); return -1; } tu_hangup(tu); tu_unref(tu, "Unregister tu from pbx"); pbx->exts[ext-1] = 0; pthread_mutex_unlock(&pbx->mutex); return 0; } #endif /* * Use the PBX to initiate a call from a specified TU to a specified extension. * * @param pbx The PBX registry. * @param tu The TU that is initiating the call. * @param ext The extension number to be called. * @return 0 if dialing succeeds, otherwise -1. */ #if 0 int pbx_dial(PBX *pbx, TU *tu, int ext) { if (!pbx || !tu) { debug("ERROR: pbx or tu does not exist"); return -1; } if (ext > PBX_MAX_EXTENSIONS + 1 || ext < 1) { debug("ERROR: ext is out of range"); return -1; } pthread_mutex_lock(&pbx->mutex); int status = tu_dial(tu, pbx->exts[ext-1]); pthread_mutex_unlock(&pbx->mutex); return status; } #endif