static void *csHeartbeat(void *parm) { CsState *csState = (CsState *) parm; pthread_mutex_t mutex; pthread_cond_t cv; int cycleCount = 6; int i; Venture *venture; int j; Unit *unit; Cell *cell; int result; struct timeval workTime; struct timespec deadline; CHKNULL(csState); if (pthread_mutex_init(&mutex, NULL)) { putSysErrmsg("Can't start heartbeat, mutex init failed", NULL); return NULL; } if (pthread_cond_init(&cv, NULL)) { pthread_mutex_destroy(&mutex); putSysErrmsg("Can't start heartbeat, cond init failed", NULL); return NULL; } #ifndef mingw sigset_t signals; sigfillset(&signals); pthread_sigmask(SIG_BLOCK, &signals, NULL); #endif while (1) { lockMib(); if (cycleCount > 5) /* Every N5_INTERVAL sec. */ { cycleCount = 0; stopOtherConfigServers(csState); } for (i = 1; i <= MAX_VENTURE_NBR; i++) { venture = (_mib(NULL))->ventures[i]; if (venture == NULL) continue; for (j = 0; j <= MAX_UNIT_NBR; j++) { unit = venture->units[j]; if (unit == NULL || (cell = unit->cell)->mamsEndpoint.ept == NULL) { continue; } if (cell->heartbeatsMissed == 3) { clearMamsEndpoint (&(cell->mamsEndpoint)); } else if (cell->heartbeatsMissed < 3) { if (sendMamsMsg (&cell->mamsEndpoint, &csState->tsif, heartbeat, 0, 0, NULL) < 0) { putErrmsg("Can't send \ heartbeat.", NULL); } } cell->heartbeatsMissed++; } } /* Now sleep for N3_INTERVAL seconds. */ unlockMib(); getCurrentTime(&workTime); deadline.tv_sec = workTime.tv_sec + N3_INTERVAL; deadline.tv_nsec = workTime.tv_usec * 1000; pthread_mutex_lock(&mutex); result = pthread_cond_timedwait(&cv, &mutex, &deadline); pthread_mutex_unlock(&mutex); if (result) { errno = result; if (errno != ETIMEDOUT) { putSysErrmsg("Heartbeat failure", NULL); break; } } cycleCount++; }
static void *receivePdus(void *parm) { RxThreadParms *parms = (RxThreadParms *) parm; char ownEid[64]; Sdr sdr; BpDelivery dlv; int contentLength; ZcoReader reader; unsigned char *buffer; buffer = MTAKE(CFDP_MAX_PDU_SIZE); if (buffer == NULL) { putErrmsg("bputa receiver thread can't get buffer.", NULL); parms->running = 0; return NULL; } isprintf(ownEid, sizeof ownEid, "ipn:" UVAST_FIELDSPEC ".%u", getOwnNodeNbr(), CFDP_RECV_SVC_NBR); if (bp_open(ownEid, &(parms->rxSap)) < 0) { MRELEASE(buffer); putErrmsg("CFDP can't open own 'recv' endpoint.", ownEid); parms->running = 0; return NULL; } sdr = bp_get_sdr(); writeMemo("[i] bputa input has started."); while (parms->running) { if (bp_receive(parms->rxSap, &dlv, BP_BLOCKING) < 0) { putErrmsg("bputa bundle reception failed.", NULL); parms->running = 0; continue; } switch (dlv.result) { case BpEndpointStopped: parms->running = 0; break; case BpPayloadPresent: contentLength = zco_source_data_length(sdr, dlv.adu); CHKNULL(sdr_begin_xn(sdr)); zco_start_receiving(dlv.adu, &reader); if (zco_receive_source(sdr, &reader, contentLength, (char *) buffer) < 0) { sdr_cancel_xn(sdr); putErrmsg("bputa can't receive bundle ADU.", itoa(contentLength)); parms->running = 0; continue; } if (sdr_end_xn(sdr) < 0) { putErrmsg("bputa can't handle bundle delivery.", NULL); parms->running = 0; continue; } if (cfdpHandleInboundPdu(buffer, contentLength) < 0) { putErrmsg("bputa can't handle inbound PDU.", NULL); parms->running = 0; } break; default: break; } bp_release_delivery(&dlv, 1); /* Make sure other tasks have a chance to run. */ sm_TaskYield(); } bp_close(parms->rxSap); MRELEASE(buffer); writeMemo("[i] bputa input has stopped."); return NULL; }
void * lyst_data(LystElt elt) { CHKNULL(elt); return elt->data; }
static void *sendItems(void *parm) { SenderThreadParms *stp = (SenderThreadParms *) parm; Sdr sdr; char buffer[MAX_LINE_LEN + 1]; int length; Object extent; Object item = 0; snooze(3); /* Let sda_run get started. */ sdr = getIonsdr(); while (stp->running) { if (fgets(buffer, MAX_LINE_LEN, stdin) == NULL) { sda_interrupt(); stp->running = 0; continue; /* End of file, and test. */ } length = istrlen(buffer, MAX_LINE_LEN) + 1; /* Send NULL-terminated text line as an SDA item. */ CHKNULL(sdr_begin_xn(sdr)); extent = sdr_insert(sdr, buffer, length); if (extent) { item = ionCreateZco(ZcoSdrSource, extent, 0, length, 0, 0, ZcoOutbound, NULL); } if (sdr_end_xn(sdr) < 0 || item == 0 || item == (Object) ERROR) { putErrmsg("Service data item insertion failed.", NULL); sda_interrupt(); stp->running = 0; continue; } if (sda_send(stp->destEngineId, SDA_TEST_CLIENT, item) < 0) { putErrmsg("Service data item sending failed.", NULL); sda_interrupt(); stp->running = 0; continue; } CHKNULL(sdr_begin_xn(sdr)); zco_destroy(sdr, item); if (sdr_end_xn(sdr) < 0) { putErrmsg("Service data item deletion failed.", NULL); sda_interrupt(); stp->running = 0; continue; } } writeErrmsgMemos(); writeMemo("[i] sdatest sender thread has ended."); return NULL; }
LystElt lyst_prev(LystElt elt) { CHKNULL(elt); return elt->prev; }
Lyst lyst_lyst(LystElt elt) { CHKNULL(elt); return elt->lyst; }
LystElt lyst_last(Lyst list) { CHKNULL(list); return list->last; }
LystElt lyst_next(LystElt elt) { CHKNULL(elt); return elt->next; }
int mknod(char *p, int m, int d) { CHKNULL(p); return (_syscall(SYS_mknod, p, m, d)); }
LystElt lyst_first(Lyst list) { CHKNULL(list); return list->first; }
IonVdb * createIonVdb(char * ionvdbName) { IonVdb *vdb = NULL; PsmAddress vdbAddress; PsmAddress elt; Sdr sdr; PsmPartition ionwm; IonDB iondb; char * name = ionvdbName; /* Attaching to volatile database. */ ionwm = getIonwm(); if (psm_locate(ionwm, name, &vdbAddress, &elt) < 0) { putErrmsg("Failed searching for vdb.", name); return NULL; } if (elt) { vdb = (IonVdb *) psp(ionwm, vdbAddress); } if (vdb != NULL) return vdb; /* ION volatile database doesn't exist yet. */ sdr = getIonsdr(); CHKNULL(sdr_begin_xn(sdr)); /* To lock memory. */ vdbAddress = psm_zalloc(ionwm, sizeof(IonVdb)); if (vdbAddress == 0) { sdr_exit_xn(sdr); putErrmsg("No space for volatile database.", name); return NULL; } vdb = (IonVdb *) psp(ionwm, vdbAddress); memset((char *) vdb, 0, sizeof(IonVdb)); if ((vdb->nodes = sm_rbt_create(ionwm)) == 0 || (vdb->neighbors = sm_rbt_create(ionwm)) == 0 || (vdb->contactIndex = sm_rbt_create(ionwm)) == 0 || (vdb->rangeIndex = sm_rbt_create(ionwm)) == 0 || (vdb->timeline = sm_rbt_create(ionwm)) == 0 || (vdb->probes = sm_list_create(ionwm)) == 0 || (vdb->requisitions[0] = sm_list_create(ionwm)) == 0 || (vdb->requisitions[1] = sm_list_create(ionwm)) == 0 || psm_catlg(ionwm, name, vdbAddress) < 0) { sdr_exit_xn(sdr); putErrmsg("Can't initialize volatile database.", name); return NULL; } vdb->clockPid = ERROR; /* None yet. */ sdr_read(sdr, (char *) &iondb, getIonDbObject(), sizeof(IonDB)); vdb->deltaFromUTC = iondb.deltaFromUTC; sdr_exit_xn(sdr); /* Unlock memory. */ //fprintf(stderr, "ionVdb created: %d\n", getOwnNodeNbr()); return vdb; }
static IonVdb *_ionvdb(char **name) { static IonVdb *vdb = NULL; PsmAddress vdbAddress; PsmAddress elt; Sdr sdr; PsmPartition ionwm; IonDB iondb; if (name) { if (*name == NULL) /* Terminating. */ { vdb = NULL; return vdb; } /* Attaching to volatile database. */ ionwm = _ionwm(NULL); if (psm_locate(ionwm, *name, &vdbAddress, &elt) < 0) { putErrmsg("Failed searching for vdb.", *name); return NULL; } if (elt) { vdb = (IonVdb *) psp(ionwm, vdbAddress); return vdb; } /* ION volatile database doesn't exist yet. */ sdr = _ionsdr(NULL); CHKNULL(sdr_begin_xn(sdr)); /* To lock memory. */ vdbAddress = psm_zalloc(ionwm, sizeof(IonVdb)); if (vdbAddress == 0) { sdr_exit_xn(sdr); putErrmsg("No space for volatile database.", *name); return NULL; } vdb = (IonVdb *) psp(ionwm, vdbAddress); memset((char *) vdb, 0, sizeof(IonVdb)); vdb->zcoSemaphore = sm_SemCreate(SM_NO_KEY, SM_SEM_FIFO); if (vdb->zcoSemaphore == SM_SEM_NONE) { sdr_exit_xn(sdr); putErrmsg("Can't initialize volatile database.", *name); return NULL; } sm_SemTake(vdb->zcoSemaphore); /* Lock it. */ if ((vdb->nodes = sm_rbt_create(ionwm)) == 0 || (vdb->neighbors = sm_rbt_create(ionwm)) == 0 || (vdb->contactIndex = sm_rbt_create(ionwm)) == 0 || (vdb->rangeIndex = sm_rbt_create(ionwm)) == 0 || (vdb->timeline = sm_rbt_create(ionwm)) == 0 || (vdb->probes = sm_list_create(ionwm)) == 0 || psm_catlg(ionwm, *name, vdbAddress) < 0) { sdr_exit_xn(sdr); putErrmsg("Can't initialize volatile database.", *name); return NULL; } vdb->clockPid = ERROR; /* None yet. */ sdr_read(sdr, (char *) &iondb, _iondbObject(NULL), sizeof(IonDB)); vdb->deltaFromUTC = iondb.deltaFromUTC; sdr_exit_xn(sdr); /* Unlock memory. */ } return vdb; }
static void *getBundles(void *parm) { RxThreadParms *parms = (RxThreadParms *) parm; char ownEid[64]; Sdr sdr = getIonsdr(); BpDelivery dlv; uvast profNum; Scalar seqNum; char type; unsigned int aduLength; int bytesRemaining; ZcoReader reader; unsigned char *buffer; int bytesToRead; int sdnvLength; unsigned char *cursor; isprintf(ownEid, sizeof ownEid, "ipn:" UVAST_FIELDSPEC ".%d", getOwnNodeNbr(), DTPC_RECV_SVC_NBR); if (bp_open(ownEid, &(parms->rxSap)) < 0) { putErrmsg("DTPC can't open own 'recv' endpoint.", ownEid); parms->running = 0; return NULL; } writeMemo("[i] dtpcd receiver thread has started."); while (parms->running) { if (bp_receive(parms->rxSap, &dlv, BP_BLOCKING) < 0) { putErrmsg("dtpcd bundle reception failed.", NULL); parms->running = 0; continue; } switch (dlv.result) { case BpEndpointStopped: parms->running = 0; break; case BpPayloadPresent: CHKNULL(sdr_begin_xn(sdr)); /* Since the max length of a Sdnv is 10 bytes, * read 21 bytes to be sure that the Profile * and Sequence number Sdnvs plus the type * were read. */ aduLength = zco_source_data_length(sdr, dlv.adu); bytesRemaining = aduLength; if (aduLength < 21) /* Just in case we receive * a very small adu. */ { bytesToRead = aduLength; } else { bytesToRead = 21; } buffer = MTAKE(bytesToRead); if (buffer == NULL) { putErrmsg("Out of memory.",NULL); return NULL; } cursor = buffer; zco_start_receiving(dlv.adu, &reader); if (zco_receive_headers(sdr, &reader, bytesToRead, (char *) buffer) < 0) { putErrmsg("dtpcd can't receive ADU header.", itoa(bytesToRead)); sdr_cancel_xn(sdr); MRELEASE(buffer); parms->running = 0; continue; } type = *cursor; /* Get the type byte. */ cursor++; bytesRemaining--; sdnvLength = decodeSdnv(&profNum, cursor); cursor += sdnvLength; bytesRemaining -= sdnvLength; sdnvLength = sdnvToScalar(&seqNum, cursor); cursor += sdnvLength; bytesRemaining -= sdnvLength; /* Mark remaining bytes as source data. */ zco_delimit_source(sdr, dlv.adu, cursor - buffer, bytesRemaining); zco_strip(sdr, dlv.adu); MRELEASE(buffer); if (sdr_end_xn(sdr) < 0) { putErrmsg("dtpcd can't handle bundle delivery.", NULL); parms->running = 0; continue; } switch (type) { case 0x00: /* Received an adu. */ switch (handleInAdu(sdr, &dlv, profNum, seqNum)) { case -1: putErrmsg("dtpcd can't handle inbound \ adu.", NULL); parms->running = 0; continue; case 1: if (parseInAdus(sdr) < 0) { putErrmsg("dtpcd can't parse \ inbound adus.", NULL); parms->running = 0; continue; } case 0: /* Intentional fall-through to * next case. */ default: if (dlv.ackRequested) { if (sendAck(parms->txSap, profNum, seqNum, &dlv) < 0) { putErrmsg("dtpcd can't \ send ack.", NULL); parms->running = 0; continue; } } break; } break; case 0x01: /* Received an ACK. */ if (handleAck(sdr, &dlv, profNum, seqNum) < 0) { putErrmsg("dtpcd can't handle ACK.", NULL); parms->running = 0; continue; } break; default: writeMemo("[?] Invalid item type. Corrupted \ item?"); break; } default: break; }
void *psp(PsmPartition partition, PsmAddress address) { CHKNULL(partition); return (address < sizeof(PartitionMap) ? NULL : (partition->space) + address); }
char *psm_space(PsmPartition partition) { CHKNULL(partition); return partition->space; }