/* * Function: enqueue_packet * Purpose: move a newly read packet onto the appropriate queue * of read packets * * Params: * In/Out: ds State structure with new packet * * Returns: Nothing */ static void enqueue_packet(DevSWState *ds) { struct data_packet *dp = &ds->ds_activeread.dc_packet; Packet *packet = ds->ds_nextreadpacket; /* * transfer the length */ packet->pk_length = dp->len; /* * take this packet out of the incoming slot */ ds->ds_nextreadpacket = NULL; /* * try to put it on the correct input queue */ if (illegalDevChanID(dp->type)) { /* this shouldn't happen */ WARN("Illegal type for Rx packet"); DevSW_FreePacket(packet); } else Adp_addToQueue(&ds->ds_readqueue[dp->type], packet); }
AdpErrs DevSW_Close (DeviceDescr *device, const DevChanID type) { DevSWState *ds = (DevSWState *)(device->SwitcherState); Packet *pk; if ((ds->ds_opendevchans & (1 << type)) == 0) return adp_device_not_open; ds->ds_opendevchans &= ~(1 << type); /* * if this is the last close for this channel, then inform the driver */ if (ds->ds_opendevchans == 0) device->DeviceClose(); /* * release all packets of the appropriate type */ for (pk = Adp_removeFromQueue(&(ds->ds_readqueue[type])); pk != NULL; pk = Adp_removeFromQueue(&(ds->ds_readqueue[type]))) DevSW_FreePacket(pk); /* Free memory */ free ((char *) device->SwitcherState); device->SwitcherState = 0x0; /* that's all */ return adp_ok; }
/* * Function: FireCallback * Purpose: Pass received packet along to the callback routine for * the appropriate channel * * Params: * Input: packet The received packet. * * Returns: Nothing * * Post-conditions: The Target-to-Host sequence number for the channel * will have been incremented. */ static void FireCallback(Packet *packet) { ChannelID chan; struct Channel *ch; /* * is this a sensible channel number? */ chan = *(packet->pk_buffer); if (invalidChannelID(chan)) { printf("ERROR: invalid ChannelID received from target\n"); /* * free the packet's resources, 'cause no-one else will */ DevSW_FreePacket(packet); return; } /* * looks OK - increment sequence number, and pass packet to callback */ ch = channels + chan; (ch->callback)(packet, ch->callback_state); }
static AdpErrs check_seq(unsigned char msg_home, unsigned char msg_oppo) { Packet *tmp_pkt; UNUSED(msg_oppo); /* * check if we have got an ack for anything and if so remove it from the * queue */ if (msg_home == (unsigned char)(OppoSeq + 1)) { /* * arrived in sequence can increment our opposing seq number and remove * the relevant packet from our queue * check that the packet we're going to remove really is the right one */ tmp_pkt = writeQueueRoot; while ((tmp_pkt->pk_next != NULL) && (tmp_pkt->pk_next->pk_buffer[CF_HOME_SEQ_BYTE_POS] != OppoSeq)){ tmp_pkt = tmp_pkt->pk_next; } OppoSeq++; if (tmp_pkt->pk_next == NULL) { #ifdef DEBUG printf("trying to remove a non existant packet\n"); #endif return adp_bad_packet; } else { Packet *tmp = tmp_pkt->pk_next; #ifdef RET_DEBUG printf("removing a packet from the root queue\n"); #endif tmp_pkt->pk_next = tmp_pkt->pk_next->pk_next; /* remove the appropriate packet */ DevSW_FreePacket(tmp); return adp_ok; } } else if (msg_home < (unsigned char) (OppoSeq+1)){ /* already received this message */ #ifdef RET_DEBUG printf("sequence numbers low\n"); #endif return adp_seq_low; } else { /* we've missed something */ #ifdef RET_DEBUG printf("sequence numbers high\n"); #endif return adp_seq_high; } }
void Adp_initSeq( void ) { Packet *tmp_pkt = writeQueueSend; HomeSeq = 0; OppoSeq = 0; if ( writeQueueSend != NULL) { while (writeQueueSend->pk_next !=NULL) { tmp_pkt = writeQueueSend; writeQueueSend = tmp_pkt->pk_next; DevSW_FreePacket(tmp_pkt); } } tmp_pkt = writeQueueRoot; if ( writeQueueRoot == NULL) return; while (writeQueueRoot->pk_next !=NULL) { tmp_pkt = writeQueueRoot; writeQueueRoot = tmp_pkt->pk_next; DevSW_FreePacket(tmp_pkt); } return; }
/* * Function: DummyCallback * Purpose: Default callback routine to handle unexpected input * on a channel * * Params: * Input: packet The received packet * * state Contains nothing of significance * * Returns: Nothing */ static void DummyCallback(Packet *packet, void *state) { ChannelID chan; const char fmt[] = "Unexpected read on channel %u, length %d\n"; char fmtbuf[(sizeof(fmt) + 24)]; UNUSED(state); chan = *(packet->pk_buffer); sprintf(fmtbuf, fmt, chan, packet->pk_length); printf("%s", fmtbuf); /* * junk this packet */ DevSW_FreePacket(packet); }
static void async_process_appl_read(void) { Packet *packet; AdpErrs adp_err; /* see if there is anything for the DC_APPL channel */ adp_err = DevSW_Read(deviceToUse, DC_APPL, &packet, FALSE); if (adp_err == adp_ok && packet != NULL) { /* got an application packet on a shared device */ #ifdef DEBUG printf("GOT DC_APPL PACKET: len %d\nData: ", packet->pk_length); { unsigned int c; for ( c = 0; c < packet->pk_length; ++c ) printf( "%02X ", packet->pk_buffer[c] ); } printf("\n"); #endif if (dc_appl_handler != NULL) { dc_appl_handler( deviceToUse, packet ); } else { /* for now, just free it!! */ #ifdef DEBUG printf("no handler - dropping DC_APPL packet\n"); #endif DevSW_FreePacket( packet ); } } }
int HandleSysMessage(Packet *packet, hsys_state *stateptr) { unsigned int reason_code, mode, len, c, nbytes, nbtotal, nbtogo = 0; long posn, fl; char character; int err; /* Note: We must not free the buffer passed in as the callback handler */ /* expects to do this. Freeing any other buffers we have malloced */ /* ourselves is acceptable */ unsigned char *buffp = ((unsigned char *)BUFFERDATA(packet->pk_buffer))+16; /* buffp points to the parameters*/ /* the invidual messages, excluding*/ /* standard SYS fields (debugID, */ /* osinfo and reasoncode) */ unsigned char *buffhead = (unsigned char *)(packet->pk_buffer); int DebugID, OSInfo1, OSInfo2, count; const char* fmode[] = {"r","rb","r+","r+b", "w","wb","w+","w+b", "a","ab","a+","a+b", "r","r","r","r"} /* last 4 are illegal */ ; FILEHANDLE fh; /* fh is used as an index to the real file handle * in OSptr */ FILE *fhreal; unpack_message(BUFFERDATA(buffhead), "%w%w%w%w", &reason_code, &DebugID, &OSInfo1, &OSInfo2); /* Extract reason code from buffer. */ reason_code &= 0xFFFF; /* Strip away direction bit, OSInfo and */ /* DebugInfo fields. Will want to do some */ /* sort of validation on this later. */ switch(reason_code) { case CL_WriteC: /* Write a character to the terminal. */ /* byte data -> word status */ { #ifdef DEBUG int c = (int)(*buffp); printf("CL_WriteC: [%02x]>%c<", c, isprint(c) ? c : '.'); #endif stateptr->hostif->writec(stateptr->hostif->hostosarg, (int)(*buffp)); DevSW_FreePacket(packet); return msgsend(CI_CLIB,"%w%w%w%w%w", CL_WriteC|HtoT, DebugID, OSInfo1, OSInfo2, NoError); } case CL_Write0: /* Write a null terminated string to the terminal. */ { unpack_message(buffp, "%w", &len); DebugCheckNullTermString("CL_Write0", TRUE, len, buffp+4); stateptr->hostif->write(stateptr->hostif->hostosarg, (char *) buffp+4, len); DevSW_FreePacket(packet); return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Write0|HtoT, DebugID, OSInfo1, OSInfo2, NoError); } case CL_ReadC: /* Read a byte from the terminal */ { DebugPrintF(("CL_ReadC: ")); DevSW_FreePacket(packet); character = stateptr->hostif->readc(stateptr->hostif->hostosarg); DebugPrintF(("\nCL_ReadC returning [%02x]>%c<\n", character, isprint(character) ? character : '.')); return msgsend(CI_CLIB, "%w%w%w%w%w%b", CL_ReadC|HtoT, DebugID, OSInfo1, OSInfo2, NoError, character); } case CL_System: /* Pass NULL terminated string to the hosts command * interpreter. As it is nULL terminated we dont need * the length */ { unpack_message(buffp, "%w", &len); DebugCheckNullTermString("CL_System", TRUE, len, buffp+4); err = system((char *)buffp+4); /* Use the string in the buffer */ stateptr->last_errno = errno; DebugCheckErr("system", TRUE, err, stateptr->last_errno); err = msgsend(CI_CLIB, "%w%w%w%w%w%w", CL_System|HtoT, DebugID, OSInfo1, OSInfo2, NoError, err); DevSW_FreePacket(packet); return err; } case CL_GetCmdLine: /* Returns the command line used to call the program */ { /* Note: we reuse the packet here, this may not always be desirable */ /* /* TODO: Use long buffers if possible */ DebugPrintF(("CL_GetCmdLine: \"%s\"\n", *(stateptr->CommandLine))); if (buffhead!=NULL) { len = strlen(*(stateptr->CommandLine)); if (len > Armsd_BufferSize-24) len = Armsd_BufferSize-24; packet->pk_length = len + msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w", CL_GetCmdLine|HtoT, DebugID, OSInfo1, OSInfo2, NoError, len); strncpy((char *) BUFFERDATA(buffhead)+24,*(stateptr->CommandLine), len); Adp_ChannelWrite(CI_CLIB, packet);/* Send message. */ return 0; } else return -1; } case CL_Clock: /* Return the number of centiseconds since the support */ /* code started executing */ { time_t retTime = time(NULL); if (retTime == (time_t)-1) stateptr->last_errno = errno; else retTime *=100; DebugPrintF(("CL_Clock: %lu\n", retTime)); DebugCheckErr("time", TRUE, (retTime == (time_t)-1), stateptr->last_errno); DevSW_FreePacket(packet); return msgsend(CI_CLIB, "%w%w%w%w%w%w",CL_Clock|HtoT, DebugID, OSInfo1, OSInfo2, NoError, retTime); } case CL_Time: /* return time, in seconds since the start of 1970 */ { time_t retTime = time(NULL); if (retTime == (time_t)-1) stateptr->last_errno = errno; DebugPrintF(("CL_Time: %lu\n", retTime)); DebugCheckErr("time", TRUE, (retTime == (time_t)-1), stateptr->last_errno); DevSW_FreePacket(packet); return msgsend(CI_CLIB,"%w%w%w%w%w%w",CL_Time|HtoT, DebugID, OSInfo1, OSInfo2, NoError, retTime); } case CL_Remove: /* delete named in the null terminated string */ { /* Removing an open file will cause problems but once again * its not our problem, likely result is a tangled FileTable */ /* As the filename is passed with a null terminator we can use it * straight out of the buffer without copying it.*/ unpack_message(buffp, "%w", &len); DebugCheckNullTermString("CL_Remove", TRUE, len, buffp+4); err=remove((char *)buffp+4); stateptr->last_errno = errno; DevSW_FreePacket(packet); DebugCheckErr("remove", TRUE, err, stateptr->last_errno); return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Remove|HtoT, DebugID, OSInfo1, OSInfo2, err?-1:NoError); } case CL_Rename: /* rename file */ { /* Rename(word nbytes, bytes oname, word nbytes, bytes nname) * return(byte status) */ unsigned int len2; unpack_message(buffp, "%w", &len); DebugCheckNullTermString("CL_Rename", FALSE, len, buffp+4); unpack_message(buffp+5+len, "%w", &len2); DebugCheckNullTermString("to", TRUE, len2, buffp+9+len); /* Both names are passed with null terminators so we can use them * directly from the buffer. */ err = rename((char *)buffp+4, (char *)buffp+9+len); stateptr->last_errno = errno; DebugCheckErr("rename", TRUE, err, stateptr->last_errno); DevSW_FreePacket(packet); return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Rename|HtoT, DebugID, OSInfo1, OSInfo2, (err==0)? NoError : -1); } case CL_Open: /* open the file */ { /* Open(word nbytes, bytes name, byte mode) * return(word handle) */ unpack_message(buffp, "%w", &len); /* get the open mode */ unpack_message((buffp)+4+len+1, "%w", &mode); DebugCheckNullTermString("CL_Open", FALSE, len, buffp+4); DebugPrintF(("mode: %d\n", mode)); /* do some checking on the file first? */ /* check if its a tty */ if (strcmp((char *)buffp+4, ":tt")==0 && (mode==0||mode==1)) { /* opening tty "r" */ fhreal = stdin; stateptr->last_errno = errno; DebugPrintF(("\tstdin ")); } else if (strcmp((char *)buffp+4, ":tt")== 0 && (mode==4||mode==5)) { /* opening tty "w" */ fhreal = stdout; stateptr->last_errno = errno; DebugPrintF(("\tstdout ")); } else { fhreal = fopen((char *)buffp+4, fmode[mode&0xFF]); stateptr->last_errno = errno; DebugCheckNonNull("fopen", FALSE, fhreal, stateptr->last_errno); } DevSW_FreePacket(packet); c = NONHANDLE; if (fhreal != NULL) { /* update filetable */ for (c=3; c < HSYS_FOPEN_MAX; c++) { /* allow for stdin, stdout, stderr (!!! WHY? MJG) */ if (stateptr->OSptr->FileTable[c] == NULL) { stateptr->OSptr->FileTable[c]= fhreal; stateptr->OSptr->FileFlags[c]= mode & 1; DebugPrintF(("fh: %d\n", c)); break; } else if (c == HSYS_FOPEN_MAX) { /* no filehandles free */ DebugPrintF(("no free fh: %d\n", c)); stateptr->last_errno = EMFILE; } } } else { /* c = NULL;*/ DebugPrintF(("error fh: %d\n", c)); } (void) msgsend(CI_CLIB, "%w%w%w%w%w", CL_Open|HtoT, DebugID, OSInfo1, OSInfo2, c); return 0; } case CL_Close: /* close the file pointed to by the filehandle */ { unpack_message(buffp, "%w", &fh); DebugPrintF(("CL_Close: fh %d\n", fh)); DevSW_FreePacket(packet); fhreal = hsysGetRealFileHandle(stateptr, fh, NULL); if (fhreal == NULL) err = -1; else { if (fhreal == stdin || fhreal == stdout || fhreal == stderr) { stateptr->last_errno = errno; DebugPrintF(("\tskipping close of std*\n")); err = 0; } else { err = fclose(fhreal); if (err == 0) stateptr->OSptr->FileTable[fh]=NULL; stateptr->last_errno = errno; DebugCheckErr("fclose", TRUE, err, stateptr->last_errno); } } return msgsend(CI_CLIB,"%w%w%w%w%w", CL_Close|HtoT, DebugID, OSInfo1, OSInfo2, err); } case CL_Write: { /* Write(word handle, word nbtotal, word nbytes, bytes data) * return(word nbytes) * WriteX(word nbytes, bytes data) * return(word nbytes) */ unsigned char *rwdata = NULL, *rwhead = NULL; unsigned char *write_source = NULL; char flags; FILE *fhreal; unsigned int ack_reason = CL_Write; /* first ack is for CL_Write */ err = -1; /* err == 0 is fwrite() error indication */ unpack_message(buffp, "%w%w%w", &fh, &nbtotal, &nbytes); DebugPrintF(("CL_Write: fh %d nbtotal %u nbytes %u\n", fh, nbtotal, nbytes)); fhreal = hsysGetRealFileHandle(stateptr, fh, &flags); nbtogo = nbtotal; /* deal with the file handle */ if (fhreal == NULL) err = 0; else { if (flags & READOP) fseek(fhreal,0,SEEK_CUR); stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP; nbtogo -= nbytes; if (nbtogo > 0) { write_source = rwdata = rwhead = (unsigned char *)malloc(nbtotal); if (rwhead == NULL) { fprintf(stderr, "OUT OF MEMORY at line %d in %s\n", __LINE__, __FILE__); return -1; } memcpy(rwdata, buffp+12, nbytes); rwdata += nbytes; } else write_source = buffp+12; } do { /* at least once!! */ if (nbtogo == 0 && err != 0) { /* Do the actual write! */ if (fhreal == stdout || fhreal == stderr) { stateptr->hostif->write(stateptr->hostif->hostosarg, (char *)write_source, nbtotal); } else err = fwrite(write_source, 1, nbtotal, fhreal); stateptr->last_errno = errno; DebugCheckErr("fwrite", TRUE, (err == 0), stateptr->last_errno); } DevSW_FreePacket(packet); if (msgsend(CI_CLIB,"%w%w%w%w%w%w", ack_reason|HtoT, DebugID, OSInfo1, OSInfo2, (err == 0), nbtogo)) { fprintf(stderr, "COULD NOT REPLY at line %d in %s\n", __LINE__, __FILE__); if (rwhead != NULL) free(rwhead); return -1; } if (nbtogo == 0 || err == 0) { DebugPrintF(("\twrite complete - returning\n")); if (rwhead != NULL) free(rwhead); return 0; } else { /* await extension */ ack_reason = CL_WriteX; packet = DevSW_AllocatePacket(Armsd_BufferSize); if (packet == NULL) { fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n", __LINE__, __FILE__); if (rwhead != NULL) free(rwhead); return -1; } Adp_ChannelRegisterRead(CI_CLIB, NULL, NULL); Adp_ChannelRead(CI_CLIB, &packet); Adp_ChannelRegisterRead(CI_CLIB, (ChannelCallback)HandleSysMessage, stateptr); buffhead = packet->pk_buffer; unpack_message(BUFFERDATA(buffhead), "%w%w%w%w%w", &reason_code, &DebugID, &OSInfo1, &OSInfo2, &nbytes); if (reason_code != (CL_WriteX|TtoH)) { DevSW_FreePacket(packet); free(rwhead); fprintf(stderr, "EXPECTING CL_WriteX GOT %u at line %d in %s\n", reason_code, __LINE__, __FILE__); return -1; } DebugPrintF(("CL_WriteX: nbytes %u\n", nbytes)); memcpy(rwdata, BUFFERDATA(buffhead)+20, nbytes); rwdata += nbytes; nbtogo -= nbytes; } } while (TRUE); /* will return when done */ } case CL_WriteX: /* * NOTE: if we've got here something has gone wrong * CL_WriteX's should all be picked up within the * CL_Write loop, probably best to return an error here * do this for the moment just so we do actually return */ fprintf(stderr, "ERROR: unexpected CL_WriteX message received\n"); return -1; case CL_Read: { /* Read(word handle, word nbtotal) * return(word nbytes, word nbmore, bytes data) */ /* ReadX() * return(word nbytes, word nbmore, bytes data) */ unsigned char *rwdata, *rwhead; int gotlen; unsigned int max_data_in_buffer=Armsd_BufferSize-28; char flags; FILE *fhreal; unsigned int nbleft = 0, reason = CL_Read; err = NoError; unpack_message(buffp, "%w%w", &fh, &nbtotal); DebugPrintF(("CL_Read: fh %d, nbtotal %d: ", fh, nbtotal)); rwdata = rwhead = (unsigned char *)malloc(nbtotal); if (rwdata == NULL) { fprintf(stderr, "OUT OF MEMORY at line %d in %s\n", __LINE__, __FILE__); DevSW_FreePacket(packet); return -1; } /* perform the actual read */ fhreal = hsysGetRealFileHandle(stateptr, fh, &flags); if (fhreal == NULL) { /* bad file handle */ err = -1; nbytes = 0; gotlen = 0; } else { if (flags & WRITEOP) fseek(fhreal,0,SEEK_CUR); stateptr->OSptr->FileFlags[fh] = (flags & BINARY) | WRITEOP; if (isatty_(fhreal)) { /* reading from a tty, so do some nasty stuff, reading into rwdata */ if (angel_hostif->gets(stateptr->hostif->hostosarg, (char *)rwdata, nbtotal) != 0) gotlen = strlen((char *)rwdata); else gotlen = 0; stateptr->last_errno = errno; DebugPrintF(("ttyread %d\n", gotlen)); } else { /* not a tty, reading from a real file */ gotlen = fread(rwdata, 1, nbtotal, fhreal); stateptr->last_errno = errno; DebugCheckErr("fread", FALSE, (gotlen == 0), stateptr->last_errno); DebugPrintF(("(%d)\n", gotlen)); } } nbtogo = gotlen; do { /* at least once */ if ((unsigned int) nbtogo <= max_data_in_buffer) nbytes = nbtogo; else nbytes = max_data_in_buffer; nbtogo -= nbytes; /* last ReadX needs subtle adjustment to returned nbtogo */ if (nbtogo == 0 && err == NoError && reason == CL_ReadX) nbleft = nbtotal - gotlen; else nbleft = nbtogo; count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w%w", reason|HtoT, 0, ADP_HandleUnknown, ADP_HandleUnknown, err, nbytes, nbleft); if (err == NoError) { /* copy data into buffptr */ memcpy(BUFFERDATA(buffhead)+28, rwdata, nbytes); rwdata += nbytes; count += nbytes; } DebugPrintF(("\treplying err %d, nbytes %d, nbtogo %d\n", err, nbytes, nbtogo)); packet->pk_length = count; Adp_ChannelWrite(CI_CLIB, packet); if (nbtogo == 0 || err != NoError) { /* done */ free(rwhead); return 0; } else { /* await extension */ reason = CL_ReadX; packet = DevSW_AllocatePacket(Armsd_BufferSize); if (packet == NULL) { fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n", __LINE__, __FILE__); free(rwhead); return -1; } Adp_ChannelRegisterRead(CI_CLIB, NULL, NULL); Adp_ChannelRead(CI_CLIB, &packet); Adp_ChannelRegisterRead(CI_CLIB, (ChannelCallback)HandleSysMessage, stateptr); buffhead = packet->pk_buffer; unpack_message(BUFFERDATA(buffhead),"%w", &reason_code); if (reason_code != (CL_ReadX|TtoH)) { fprintf(stderr, "EXPECTING CL_ReadX GOT %u at line %d in %s\n", reason_code, __LINE__, __FILE__); DevSW_FreePacket(packet); free(rwdata); return -1; } } } while (TRUE); /* will return above on error or when done */ } case CL_ReadX: /* If we're here something has probably gone wrong */ fprintf(stderr, "ERROR: Got unexpected CL_ReadX message\n"); return -1; case CL_Seek: { unpack_message(buffp, "%w%w", &fh, &posn); DebugPrintF(("CL_Seek: fh %d, posn %ld\n", fh, posn)); DevSW_FreePacket(packet); fhreal = hsysGetRealFileHandle(stateptr, fh, NULL); if (fhreal == NULL) err = -1; else { err = fseek(fhreal, posn, SEEK_SET); stateptr->last_errno = errno; DebugCheckErr("fseek", TRUE, err, stateptr->last_errno); } return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Seek|HtoT, DebugID, OSInfo1, OSInfo2, err); } case CL_Flen: { unpack_message(buffp, "%w", &fh); DebugPrintF(("CL_Flen: fh %d ", fh)); DevSW_FreePacket(packet); fhreal = hsysGetRealFileHandle(stateptr, fh, NULL); if (fhreal == NULL) fl = -1; else { posn = ftell(fhreal); if (fseek(fhreal, 0L, SEEK_END) < 0) { fl=-1; } else { fl = ftell(fhreal); fseek(fhreal, posn, SEEK_SET); } stateptr->last_errno = errno; } DebugPrintF(("returning len %ld\n", fl)); return msgsend(CI_CLIB, "%w%w%w%w%w", CL_Flen|HtoT, DebugID, OSInfo1, OSInfo2, fl); } case CL_IsTTY: { int ttyOrNot; unpack_message(buffp, "%w", &fh); DebugPrintF(("CL_IsTTY: fh %d ", fh)); DevSW_FreePacket(packet); fhreal = hsysGetRealFileHandle(stateptr, fh, NULL); if (fhreal == NULL) ttyOrNot = FALSE; else { ttyOrNot = isatty_(fhreal); stateptr->last_errno = errno; } DebugPrintF(("returning %s\n", ttyOrNot ? "tty (1)" : "not (0)")); return msgsend(CI_CLIB, "%w%w%w%w%w",CL_IsTTY|HtoT, DebugID, OSInfo1, OSInfo2, ttyOrNot); } case CL_TmpNam: { char *name; unsigned int tnamelen, TargetID; unpack_message(buffp, "%w%w", &tnamelen, &TargetID); DebugPrintF(("CL_TmpNam: tnamelen %d TargetID %d: ", tnamelen, TargetID)); DevSW_FreePacket(packet); TargetID = TargetID & 0xFF; if (stateptr->OSptr->TempNames[TargetID] == NULL) { if ((stateptr->OSptr->TempNames[TargetID] = (char *)malloc(L_tmpnam)) == NULL) { fprintf(stderr, "OUT OF MEMORY at line %d in %s\n", __LINE__, __FILE__); return -1; } tmpnam(stateptr->OSptr->TempNames[TargetID]); } name = stateptr->OSptr->TempNames[TargetID]; len = strlen(name) + 1; packet = DevSW_AllocatePacket(Armsd_BufferSize); if (packet == NULL) { fprintf(stderr, "COULD NOT ALLOC PACKET at line %d in %s\n", __LINE__, __FILE__); return -1; } buffhead = packet->pk_buffer; if (len > tnamelen) { DebugPrintF(("TMPNAME TOO LONG!\n")); count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w", CL_TmpNam|HtoT, DebugID, OSInfo1, OSInfo2, -1); } else { DebugPrintF(("returning \"%s\"\n", name)); count = msgbuild(BUFFERDATA(buffhead), "%w%w%w%w%w%w", CL_TmpNam|HtoT, DebugID, OSInfo1, OSInfo2, 0, len); strcpy((char *)BUFFERDATA(buffhead)+count, name); count +=len+1; } packet->pk_length = count; Adp_ChannelWrite(CI_CLIB, packet);/* Send message. */ return 0; } case CL_Unrecognised: DebugPrintF(("CL_Unrecognised!!\n")); return 0; default: fprintf(stderr, "UNRECOGNISED CL code %08x\n", reason_code); break; /* Need some sort of error handling here. */ /* A call to CL_Unrecognised should suffice */ } return -1; /* Stop a potential compiler warning */ }
static void async_process_write( const AsyncMode mode, bool *const finished ) { Packet *packet; #ifdef DEBUG static unsigned int num_written = 0; #endif /* * NOTE: here we rely in the fact that any packet in the writeQueueSend * section of the queue will need its sequence number setting up while * and packet in the writeQueueRoot section will have its sequence * numbers set up from when it was first sent so we can easily look * up the packet numbers when(if) we want to resend the packet. */ #ifdef DEBUG if (writeQueueSend!=NULL) printf("written 0x%x\n",num_written += writeQueueSend->pk_length); #endif /* * give the switcher a chance to complete any partial writes */ if (DevSW_FlushPendingWrite(deviceToUse) == adp_write_busy) { /* no point trying a new write */ return; } /* * now see whether there is anything to write */ packet = NULL; if (resending) { packet = resend_pkt; #ifdef RET_DEBUG printf("resending hseq 0x%x oseq 0x%x\n", packet->pk_buffer[CF_HOME_SEQ_BYTE_POS], packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS]); #endif } else if (writeQueueSend != NULL) { #ifdef RETRANS /* set up the sequence number on the packet */ packet = writeQueueSend; HomeSeq++; (writeQueueSend->pk_buffer[CF_OPPO_SEQ_BYTE_POS]) = OppoSeq; (writeQueueSend->pk_buffer[CF_HOME_SEQ_BYTE_POS]) = HomeSeq; (writeQueueSend->pk_buffer[CF_FLAGS_BYTE_POS]) = CF_RELIABLE; # ifdef RET_DEBUG printf("sending packet with hseq 0x%x oseq 0x%x\n", writeQueueSend->pk_buffer[CF_HOME_SEQ_BYTE_POS], writeQueueSend->pk_buffer[CF_OPPO_SEQ_BYTE_POS]); # endif #endif /* RETRANS */ } if (packet != NULL) { AdpErrs dev_err; #ifdef FAKE_BAD_LINE_TX fake_bad_line_tx(); #endif dev_err = DevSW_Write(deviceToUse, packet, DC_DBUG); if (dev_err == adp_ok) { #ifdef RETRANS if (resending) { /* check to see if we've recovered yet */ if ((packet->pk_next) == NULL){ # ifdef RET_DEBUG printf("we have recovered\n"); # endif resending = FALSE; } else { resend_pkt = resend_pkt->pk_next; } } else { /* * move the packet we just sent from the send queue to the root */ Packet *tmp_pkt, *tmp; # ifdef FAKE_BAD_LINE_TX unfake_bad_line_tx(); # endif tmp_pkt = writeQueueSend; writeQueueSend = writeQueueSend->pk_next; tmp_pkt->pk_next = NULL; if (writeQueueRoot == NULL) writeQueueRoot = tmp_pkt; else { tmp = writeQueueRoot; while (tmp->pk_next != NULL) { tmp = tmp->pk_next; } tmp->pk_next = tmp_pkt; } } #else /* not RETRANS */ /* * switcher has taken the write, so remove it from the * queue, and free its resources */ DevSW_FreePacket(Adp_removeFromQueue(&writeQueueSend)); #endif /* if RETRANS ... else ... */ if (mode == async_block_on_write) *finished = DevSW_WriteFinished(deviceToUse); } /* endif write ok */ } else /* packet == NULL */ { if (mode == async_block_on_write) *finished = DevSW_WriteFinished(deviceToUse); } }
static void async_process_dbug_read(const AsyncMode mode, bool *const finished) { Packet *packet; unsigned int msg_home, msg_oppo; AdpErrs adp_err; adp_err = DevSW_Read(deviceToUse, DC_DBUG, &packet, mode == async_block_on_read); #ifdef FAKE_BAD_LINE_RX adp_err = fake_bad_line_rx(packet, adp_err); #endif /* FAKE_BAD_LINE_RX */ if (adp_err == adp_bad_packet) { /* We got a bad packet, ask for a resend, send a resend message */ #ifdef DEBUG printf("received a bad packet\n"); #endif /* DEBUG */ send_resend_msg(DC_DBUG); } else if (packet != NULL) { /* update the heartbeat clock */ gettimeofday(&time_lastalive, NULL); /* * we got a live one here - were we waiting for it? */ if (mode == async_block_on_read) { /* not any more */ *finished = TRUE; } #ifdef RETRANS if (packet->pk_length < CF_DATA_BYTE_POS) { /* we have got a packet with no header information! */ printf("ERROR: packet with no transport header\n"); send_resend_msg(DC_DBUG); } else { # ifdef RET_DEBUG unsigned int c; # endif /* RET_DEBUG */ /* * TODO: Check to see if its acknowledgeing anything, remove * those packets it is from the queue. If it is a retrans, add the * packets to the queue */ msg_home = packet->pk_buffer[CF_HOME_SEQ_BYTE_POS]; msg_oppo = packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS]; # ifdef RET_DEBUG printf("msg seq numbers are hseq 0x%x oseq 0x%x\n", msg_home, msg_oppo); for ((c = 0); (c < packet->pk_length); c++) { printf("%02.2x", packet->pk_buffer[c]); } printf("\n"); # endif /* RET_DEBUG */ /* now was it a resend request? */ if ((packet->pk_buffer[CF_FLAGS_BYTE_POS]) & CF_RESEND) { /* we have been asked for a resend, so we had better resend */ /* * I do NOT think we can use a resend as acknowledgement for * anything, so let us NOT do this for the moment: * check_seq(msg_home, msg_oppo); */ # ifdef RET_DEBUG printf("received a resend request\n"); # endif /* RET_DEBUG */ if (HomeSeq != msg_oppo) { int found = FALSE; /* need to resend from msg_oppo +1 upwards */ DevSW_FreePacket(packet); resending = TRUE; /* find the correct packet to resend from */ packet = writeQueueRoot; while (((packet->pk_next) != NULL) && !found) { if ((packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS]) != msg_oppo+1) { resend_pkt = packet; found = TRUE; } packet = packet->pk_next; } if (!found) { panic("trying to resend non-existent packets\n"); } } else if (OppoSeq != msg_home) { /* * send a resend request telling the target where we think * the world is at */ DevSW_FreePacket(packet); send_resend_msg(DC_DBUG); } } else { /* not a resend request, let us check the sequence numbers */ if ((packet->pk_buffer[CF_CHANNEL_BYTE_POS] != CI_HBOOT) && (packet->pk_buffer[CF_CHANNEL_BYTE_POS] != CI_TBOOT)) { adp_err = check_seq((unsigned char)msg_home, (unsigned char)msg_oppo); if (adp_err == adp_seq_low) { /* we have already received this packet so discard */ DevSW_FreePacket(packet); } else if (adp_err == adp_seq_high) { /* * we must have missed a packet somewhere, discard this * packet and tell the target where we are */ DevSW_FreePacket(packet); send_resend_msg(DC_DBUG); } else { /* * now pass the packet to whoever is waiting for it */ FireCallback(packet); } } else { FireCallback(packet); } } } #else /* * now pass the packet to whoever is waiting for it */ FireCallback(packet); #endif /* RETRANS */ } }