int bp_open(char *eidString, BpSAP *bpsapPtr) { Sdr sdr; MetaEid metaEid; VScheme *vscheme; PsmAddress vschemeElt; Sap sap; VEndpoint *vpoint; PsmAddress vpointElt; CHKERR(eidString && *eidString && bpsapPtr); *bpsapPtr = NULL; /* Default, in case of failure. */ sdr = getIonsdr(); sdr_begin_xn(sdr); /* Just to lock memory. */ /* First validate the endpoint ID. */ if (parseEidString(eidString, &metaEid, &vscheme, &vschemeElt) == 0) { sdr_exit_xn(sdr); putErrmsg("Malformed EID.", eidString); return -1; } if (vschemeElt == 0) { sdr_exit_xn(sdr); putErrmsg("Scheme not known.", metaEid.schemeName); restoreEidString(&metaEid); return -1; } findEndpoint(NULL, metaEid.nss, vscheme, &vpoint, &vpointElt); if (vpointElt == 0) { sdr_exit_xn(sdr); putErrmsg("Endpoint not known.", metaEid.nss); restoreEidString(&metaEid); return -1; } /* Endpoint exists; make sure it's not already opened * by some application. */ if (vpoint->appPid > 0) /* Endpoint not closed. */ { if (sm_TaskExists(vpoint->appPid)) { sdr_exit_xn(sdr); if (vpoint->appPid == sm_TaskIdSelf()) { return 0; } restoreEidString(&metaEid); putErrmsg("Endpoint is already open.", itoa(vpoint->appPid)); return -1; } /* Application terminated without closing the * endpoint, so simply close it now. */ vpoint->appPid = -1; } /* Construct the service access point. */ sap.vpoint = vpoint; memcpy(&sap.endpointMetaEid, &metaEid, sizeof(MetaEid)); sap.endpointMetaEid.colon = NULL; sap.endpointMetaEid.schemeName = MTAKE(metaEid.schemeNameLength + 1); if (sap.endpointMetaEid.schemeName == NULL) { sdr_exit_xn(sdr); putErrmsg("Can't create BpSAP.", NULL); restoreEidString(&metaEid); return -1; } sap.endpointMetaEid.nss = MTAKE(metaEid.nssLength + 1); if (sap.endpointMetaEid.nss == NULL) { sdr_exit_xn(sdr); MRELEASE(sap.endpointMetaEid.schemeName); putErrmsg("Can't create BpSAP.", NULL); restoreEidString(&metaEid); return -1; } *bpsapPtr = MTAKE(sizeof(Sap)); if (*bpsapPtr == NULL) { sdr_exit_xn(sdr); MRELEASE(sap.endpointMetaEid.nss); MRELEASE(sap.endpointMetaEid.schemeName); putErrmsg("Can't create BpSAP.", NULL); restoreEidString(&metaEid); return -1; } istrcpy(sap.endpointMetaEid.schemeName, metaEid.schemeName, sizeof sap.endpointMetaEid.schemeName); istrcpy(sap.endpointMetaEid.nss, metaEid.nss, sizeof sap.endpointMetaEid.nss); restoreEidString(&metaEid); sap.recvSemaphore = vpoint->semaphore; memcpy((char *) *bpsapPtr, (char *) &sap, sizeof(Sap)); /* Having created the SAP, give its owner exclusive * access to the endpoint. */ vpoint->appPid = sm_TaskIdSelf(); sdr_exit_xn(sdr); /* Unlock memory. */ return 0; }
static int enqueueBundle(Bundle *bundle, Object bundleObj) { Sdr sdr = getIonsdr(); Object elt; char eidString[SDRSTRING_BUFSZ]; MetaEid metaEid; VScheme *vscheme; PsmAddress vschemeElt; char nodeName[SDRSTRING_BUFSZ]; char demux[SDRSTRING_BUFSZ]; int result; FwdDirective directive; elt = sdr_list_first(sdr, bundle->stations); if (elt == 0) { putErrmsg("Forwarding error; stations stack is empty.", NULL); return -1; } sdr_string_read(sdr, eidString, sdr_list_data(sdr, elt)); if (parseEidString(eidString, &metaEid, &vscheme, &vschemeElt) == 0) { putErrmsg("Can't parse node EID string.", eidString); return bpAbandon(bundleObj, bundle, BP_REASON_NO_ROUTE); } if (strcmp(vscheme->name, "dtn") != 0) { putErrmsg("Forwarding error; EID scheme wrong for dtn2fw.", vscheme->name); return -1; } result = parseDtn2Nss(metaEid.nss, nodeName, demux); restoreEidString(&metaEid); if (result == 0) { putErrmsg("Invalid nss in EID string, cannot forward.", eidString); return bpAbandon(bundleObj, bundle, BP_REASON_NO_ROUTE); } if (dtn2_lookupDirective(nodeName, demux, bundle, &directive) == 0) { putErrmsg("Can't find forwarding directive for EID.", eidString); return bpAbandon(bundleObj, bundle, BP_REASON_NO_ROUTE); } if (directive.action == xmit) { if (bpEnqueue(&directive, bundle, bundleObj, eidString) < 0) { putErrmsg("Can't enqueue bundle.", NULL); return -1; } if (bundle->ductXmitElt) { /* Enqueued. */ return bpAccept(bundleObj, bundle); } else { return bpAbandon(bundleObj, bundle, BP_REASON_NO_ROUTE); } } /* Can't transmit to indicated next node directly, must * forward through some other node. */ sdr_write(sdr, bundleObj, (char *) &bundle, sizeof(Bundle)); sdr_string_read(sdr, eidString, directive.eid); return forwardBundle(bundleObj, bundle, eidString); }