static void *handleNotices(void *parm) { /* Main loop for LTP notice reception and handling. */ Sdr sdr = getIonsdr(); ReceiverThreadParms *rtp = (ReceiverThreadParms *) parm; char *procName = "ltpcli"; AcqWorkArea *redWork; AcqWorkArea *greenWork; LtpNoticeType type; LtpSessionId sessionId; unsigned char reasonCode; unsigned char endOfBlock; unsigned int dataOffset; unsigned int dataLength; Object data; /* ZCO reference. */ unsigned int greenBuflen = 0; char *greenBuffer = NULL; snooze(1); /* Let main thread become interruptable. */ if (ltp_open(BpLtpClientId) < 0) { putErrmsg("ltpcli can't open client access.", itoa(BpLtpClientId)); ionKillMainThread(procName); return NULL; } redWork = bpGetAcqArea(rtp->vduct); greenWork = bpGetAcqArea(rtp->vduct); if (redWork == NULL || greenWork == NULL) { ltp_close(BpLtpClientId); putErrmsg("ltpcli can't get acquisition work areas", NULL); ionKillMainThread(procName); return NULL; } /* Can now start receiving notices. On failure, take * down the CLI. */ while (rtp->running) { if (ltp_get_notice(BpLtpClientId, &type, &sessionId, &reasonCode, &endOfBlock, &dataOffset, &dataLength, &data) < 0) { putErrmsg("Can't get LTP notice.", NULL); ionKillMainThread(procName); rtp->running = 0; continue; } switch (type) { case LtpExportSessionComplete: /* Xmit success. */ if (data == 0) /* Ignore it. */ { break; /* Out of switch. */ } if (bpHandleXmitSuccess(data, 0) < 0) { putErrmsg("Crashed on xmit success.", NULL); ionKillMainThread(procName); rtp->running = 0; break; /* Out of switch. */ } CHKNULL(sdr_begin_xn(sdr)); zco_destroy(sdr, data); if (sdr_end_xn(sdr) < 0) { putErrmsg("Crashed on data cleanup.", NULL); ionKillMainThread(procName); rtp->running = 0; } break; /* Out of switch. */ case LtpExportSessionCanceled: /* Xmit failure. */ if (data == 0) /* Ignore it. */ { break; /* Out of switch. */ } if (bpHandleXmitFailure(data) < 0) { putErrmsg("Crashed on xmit failure.", NULL); ionKillMainThread(procName); rtp->running = 0; break; /* Out of switch. */ } CHKNULL(sdr_begin_xn(sdr)); zco_destroy(sdr, data); if (sdr_end_xn(sdr) < 0) { putErrmsg("Crashed on data cleanup.", NULL); ionKillMainThread(procName); rtp->running = 0; } break; /* Out of switch. */ case LtpImportSessionCanceled: /* None of the red data for the import * session (if any) have been received * yet, so nothing to discard. In case * part or all of the import session was * green data, force deletion of retained * data. */ sessionId.sourceEngineId = 0; sessionId.sessionNbr = 0; if (handleGreenSegment(greenWork, &sessionId, 0, 0, 0, 0, NULL, NULL) < 0) { putErrmsg("Can't cancel green session.", NULL); ionKillMainThread(procName); rtp->running = 0; } break; /* Out of switch. */ case LtpRecvRedPart: if (!endOfBlock) { /* Block is partially red and * partially green. Too risky * to wait for green EOB before * clearing the work area, so * just discard the data. */ CHKNULL(sdr_begin_xn(sdr)); zco_destroy(sdr, data); if (sdr_end_xn(sdr) < 0) { putErrmsg("Crashed: partially red.", NULL); ionKillMainThread(procName); rtp->running = 0; } break; /* Out of switch. */ } if (acquireRedBundles(redWork, data, sessionId.sourceEngineId) < 0) { putErrmsg("Can't acquire bundle(s).", NULL); ionKillMainThread(procName); rtp->running = 0; } break; /* Out of switch. */ case LtpRecvGreenSegment: if (handleGreenSegment(greenWork, &sessionId, endOfBlock, dataOffset, dataLength, data, &greenBuflen, &greenBuffer) < 0) { putErrmsg("Can't handle green segment.", NULL); ionKillMainThread(procName); rtp->running = 0; } /* Discard the ZCO in any case. */ CHKNULL(sdr_begin_xn(sdr)); zco_destroy(sdr, data); if (sdr_end_xn(sdr) < 0) { putErrmsg("Crashed: green segment.", NULL); ionKillMainThread(procName); rtp->running = 0; } break; /* Out of switch. */ default: break; /* Out of switch. */ } /* Make sure other tasks have a chance to run. */ sm_TaskYield(); } writeErrmsgMemos(); writeMemo("[i] ltpcli receiver thread has ended."); /* Free resources. */ if (greenBuffer) { MRELEASE(greenBuffer); } bpReleaseAcqArea(greenWork); bpReleaseAcqArea(redWork); ltp_close(BpLtpClientId); return NULL; }
int ltpcounter(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10) { int clientId = a1; int maxBytes = a2; #else int main(int argc, char **argv) { int clientId = (argc > 1 ? strtol(argv[1], NULL, 0) : 0); int maxBytes = (argc > 2 ? strtol(argv[2], NULL, 0) : 0); #endif IonAlarm alarm = { 5, 0, showProgress, NULL }; pthread_t alarmThread; int state = 1; LtpNoticeType type; LtpSessionId sessionId; unsigned char reasonCode; unsigned char endOfBlock; unsigned int dataOffset; unsigned int dataLength; Object data; char buffer[255]; if (clientId < 1) { PUTS("Usage: ltpcounter <client ID> [<max nbr of bytes>]"); PUTS(" Max nbr of bytes defaults to 2 billion."); return 0; } oK(_clientId(&clientId)); if (maxBytes < 1) { maxBytes = 2000000000; } if (ltp_attach() < 0) { putErrmsg("ltpcounter can't initialize LTP.", NULL); return 1; } if (ltp_open(_clientId(NULL)) < 0) { putErrmsg("ltpcounter can't open client access.", itoa(_clientId(NULL))); return 1; } ionSetAlarm(&alarm, &alarmThread); isignal(SIGINT, handleQuit); oK((_running(&state))); while (_running(NULL)) { if (ltp_get_notice(_clientId(NULL), &type, &sessionId, &reasonCode, &endOfBlock, &dataOffset, &dataLength, &data) < 0) { putErrmsg("Can't get LTP notice.", NULL); state = 0; oK((_running(&state))); continue; } switch (type) { case LtpExportSessionCanceled: isprintf(buffer, sizeof buffer, "Transmission \ canceled: source engine " UVAST_FIELDSPEC ", session %u, reason code %d.", sessionId.sourceEngineId, sessionId.sessionNbr, reasonCode); writeMemo(buffer); if (data) { ltp_release_data(data); } break; case LtpImportSessionCanceled: oK(_sessionsCanceled(1)); isprintf(buffer, sizeof buffer, "Reception canceled: \ source engine " UVAST_FIELDSPEC ", session %u, reason code %d.", sessionId.sourceEngineId, sessionId.sessionNbr, reasonCode); writeMemo(buffer); break; case LtpRecvGreenSegment: isprintf(buffer, sizeof buffer, "Green segment \ received, discarded: source engine " UVAST_FIELDSPEC ", session %u, \ offset %u, length %u, eob=%d.", sessionId.sourceEngineId, sessionId.sessionNbr, dataOffset, dataLength, endOfBlock); writeMemo(buffer); ltp_release_data(data); break; case LtpRecvRedPart: oK(_blocksReceived(1)); oK(_bytesReceived(dataLength)); ltp_release_data(data); break; default: break; } if (_bytesReceived(0) >= maxBytes) { state = 0; oK((_running(&state))); } } ionCancelAlarm(alarmThread); writeErrmsgMemos(); printCount(); PUTS("Stopping ltpcounter."); ltp_close(_clientId(NULL)); ltp_detach(); return 0; }
static void *handleNotices(void *parm) { /* Main loop for LTP notice reception and handling. */ ReceiverThreadParms *rtp = (ReceiverThreadParms *) parm; AcqWorkArea *work; LtpNoticeType type; LtpSessionId sessionId; unsigned char reasonCode; unsigned char endOfBlock; unsigned long dataOffset; unsigned long dataLength; Object data; /* ZCO reference. */ Sdr sdr; snooze(1); /* Let main thread become interruptable. */ if (ltp_open(BpLtpClientId) < 0) { putErrmsg("ltpcli can't open client access.", itoa(BpLtpClientId)); pthread_kill(rtp->mainThread, SIGTERM); return NULL; } work = bpGetAcqArea(rtp->vduct); if (work == NULL) { ltp_close(BpLtpClientId); putErrmsg("ltpcli can't get acquisition work area", NULL); pthread_kill(rtp->mainThread, SIGTERM); return NULL; } /* Can now start receiving notices. On failure, take * down the CLI. */ while (rtp->running) { if (ltp_get_notice(BpLtpClientId, &type, &sessionId, &reasonCode, &endOfBlock, &dataOffset, &dataLength, &data) < 0) { putErrmsg("Can't get LTP notice.", NULL); pthread_kill(rtp->mainThread, SIGTERM); rtp->running = 0; continue; } switch (type) { case LtpExportSessionCanceled: /* Xmit failure. */ if (data == 0) /* Ignore it. */ { break; /* Out of switch. */ } if (bpHandleXmitFailure(data) < 0) { putErrmsg("Crashed on xmit failure.", NULL); pthread_kill(rtp->mainThread, SIGTERM); rtp->running = 0; break; /* Out of switch. */ } sdr = getIonsdr(); sdr_begin_xn(sdr); zco_destroy_reference(sdr, data); if (sdr_end_xn(sdr) < 0) { putErrmsg("Crashed on data cleanup.", NULL); pthread_kill(rtp->mainThread, SIGTERM); rtp->running = 0; } break; /* Out of switch. */ case LtpImportSessionCanceled: break; /* Out of switch. */ case LtpRecvGreenSegment: case LtpRecvRedPart: if (acquireBundles(work, data, sessionId.sourceEngineId) < 0) { putErrmsg("Can't acquire bundle(s).", NULL); pthread_kill(rtp->mainThread, SIGTERM); rtp->running = 0; } break; /* Out of switch. */ default: break; /* Out of switch. */ } /* Make sure other tasks have a chance to run. */ sm_TaskYield(); } writeErrmsgMemos(); writeMemo("[i] ltpcli receiver thread has ended."); /* Free resources. */ bpReleaseAcqArea(work); ltp_close(BpLtpClientId); return NULL; }