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; }
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; }