/****** shepherd/signal_queue/get_signal() ************************************ * NAME * get_signal() -- get signal from queue * * SYNOPSIS * int get_signal() * * FUNCTION * Get signal from queue. If tehre are no more signals return -1. * * INPUTS * * RESULT * int - * >0 - signal number * -1 - There are no more signals *******************************************************************************/ int get_signal(void) { int signal = -1; if (n_sigs != 0) { n_sigs--; signal = sig_queue[next_sig]; next_sig = NEXT_INDEX(next_sig); } return signal; }
void _io_pcb_shm_tx_isr ( /* [IN] the info structure */ pointer handle ) { IO_PCB_SHM_INFO_STRUCT_PTR info_ptr; IO_PCB_STRUCT_PTR pcb_ptr; IO_PCB_SHM_BUFFER_STRUCT_PTR bd_ptr; IO_PCB_FRAGMENT_STRUCT_PTR frag_ptr; uint_16 num_frags; uint_32 cntrl; info_ptr = (IO_PCB_SHM_INFO_STRUCT_PTR)handle; _int_disable(); while (info_ptr->TXENTRIES < info_ptr->TX_LENGTH) { /* Get the address of the Tx descriptor */ bd_ptr = &info_ptr->TX_RING_PTR[info_ptr->TXLAST]; _DCACHE_INVALIDATE_LINE(bd_ptr); pcb_ptr = (IO_PCB_STRUCT_PTR) _bsp_ptov(bd_ptr->PACKET_PTR); cntrl = bd_ptr->CONTROL; /* Make sure the buffer is released by remote CPU */ if (cntrl != IO_PCB_SHM_BUFFER_ALOCATED) { break; } // Have to restore virtual addresses to free fragments num_frags = pcb_ptr->NUMBER_OF_FRAGMENTS; for(frag_ptr = (IO_PCB_FRAGMENT_STRUCT_PTR) &(pcb_ptr->FRAGMENTS[0]); num_frags; num_frags--, frag_ptr++) { frag_ptr->FRAGMENT = _bsp_ptov(frag_ptr->FRAGMENT); } /* Free PCB */ _io_pcb_free(pcb_ptr); /* Update info */ info_ptr->TX_PACKETS++; info_ptr->TXLAST = NEXT_INDEX(info_ptr->TXLAST, info_ptr->TX_LENGTH); info_ptr->TXENTRIES++; } /* Check if there is more to send */ _io_pcb_shm_tx(handle); /* Enable Interrupts */ _int_enable(); }
/****** shepherd/signal_queue/pending_sig() *********************************** * NAME * pending_sig() -- look for given signal in queue * * SYNOPSIS * int pending_sig(int sig) * * FUNCTION * Try to find signal in queue. * * INPUTS * int sig - signal number * * RESULT * int - result * 0 - not found * 1 - found *******************************************************************************/ int pending_sig(int sig) { int ret = 0; int n, i; for (n = n_sigs, i = next_sig; n; n--, i = NEXT_INDEX(i)) { if (sig_queue[i] == sig) { ret = 1; break; } } return ret; }
/****** shepherd/signal/queue/add_signal() ************************************ * NAME * add_signal() -- store signal in queue * * SYNOPSIS * int add_signal(int signal) * * FUNCTION * Store an additional signal in queue. * * INPUTS * int signal - sginal number * * RESULT * int - error state * 0 - successfull * -1 - buffer is full *******************************************************************************/ int add_signal(int signal) { int ret = -1; if (n_sigs != SGE_MAXSIG) { char err_str[256]; ret = 0; n_sigs++; sig_queue[free_sig] = signal; free_sig = NEXT_INDEX(free_sig); sprintf(err_str, "queued signal %s", sge_sys_sig2str(signal)); shepherd_trace(err_str); } return ret; }
void report_signal_queue() { char str[256]; int n, i; if (n_sigs==0) { shepherd_trace("no signals in queue"); return; } i=next_sig; for (n=n_sigs; n; n--) { sprintf(str, "%d. %d", i, sig_queue[i]); shepherd_trace(str); i = NEXT_INDEX(i); } return; }
int llwrite(int fd, unsigned char * buffer, unsigned int length) { if (linklayer.flag == RECEIVER) { printf("RECEIVER CANNOT WRITE TO SERIAL PORT\n"); return -1; } if (!initialized) { printf("SERIAL PORT ISNT INITIALIZED\n"); return -1; } unsigned char bcc2 = 0; generate_bcc2(buffer, length, &bcc2); unsigned char aux_buffer[MAX_SIZE] = ""; memcpy(aux_buffer, buffer, length); printf("bcc2 wrote: %x\n",bcc2); aux_buffer[length] = bcc2; unsigned char * stuffed_buffer = malloc(MAX_SIZE); int stuffed_length = 0; if ((stuffed_length = byteStuffing(aux_buffer, length+1, stuffed_buffer)) == -1) { printf("BYTE STUFFING ERROR\n"); return -1; } int nbytes = 0; printf("sending data!\n"); nbytes = send_data(fd, stuffed_buffer, stuffed_length); printf("wrote: %d bytes",nbytes); if (rec_resp_receiver(fd, stuffed_buffer, stuffed_length, bcc2) == -1) { printf("\n"); return -1; } free(stuffed_buffer); linklayer.sequenceNumber = NEXT_INDEX(linklayer.sequenceNumber); return nbytes; }
void _io_pcb_shm_rx_isr ( /* [IN] the info structure */ pointer handle ) { IO_PCB_SHM_INFO_STRUCT_PTR info_ptr; IO_PCB_SHM_INIT_STRUCT_PTR init_ptr; IO_PCB_STRUCT_PTR local_pcb_ptr; IO_PCB_STRUCT_PTR remote_pcb_ptr; IO_PCB_FRAGMENT_STRUCT_PTR frag_ptr; IO_PCB_SHM_BUFFER_STRUCT_PTR bd_ptr; uchar_ptr data_addr; uint_32 data_length; uint_32 cntrl; uint_16 num_frags; uint_32 max_size; boolean discard; info_ptr = (IO_PCB_SHM_INFO_STRUCT_PTR)handle; init_ptr = &info_ptr->INIT; /* Get the next RX buffer descriptor */ bd_ptr = &info_ptr->RX_RING_PTR[info_ptr->RXNEXT]; _DCACHE_INVALIDATE_LINE(bd_ptr); cntrl = bd_ptr->CONTROL; remote_pcb_ptr = (IO_PCB_STRUCT_PTR) _bsp_ptov(bd_ptr->PACKET_PTR); _DCACHE_INVALIDATE_MBYTES(remote_pcb_ptr, sizeof(*remote_pcb_ptr)); num_frags = remote_pcb_ptr->NUMBER_OF_FRAGMENTS; /* Disable interrupts */ _int_disable(); while(cntrl == (IO_PCB_SHM_BUFFER_OWN|IO_PCB_SHM_BUFFER_ALOCATED)){ discard = FALSE; /* Get a PCB */ local_pcb_ptr = _io_pcb_alloc(info_ptr->READ_PCB_POOL, FALSE); if ((local_pcb_ptr == NULL)) { break; } data_addr = local_pcb_ptr->FRAGMENTS[0].FRAGMENT; data_length = ((IO_PCB_SHM_INIT_STRUCT_PTR) &info_ptr->INIT)->INPUT_MAX_LENGTH; max_size = ((IO_PCB_SHM_INIT_STRUCT_PTR) &info_ptr->INIT)->INPUT_MAX_LENGTH; /* Copy packet */ for(frag_ptr = (IO_PCB_FRAGMENT_STRUCT_PTR) &(remote_pcb_ptr->FRAGMENTS[0]); num_frags; num_frags--, frag_ptr++) { if(frag_ptr->LENGTH > max_size){ discard = TRUE; break; } _DCACHE_INVALIDATE_MBYTES(frag_ptr->FRAGMENT, frag_ptr->LENGTH); _mem_copy(_bsp_ptov((pointer)frag_ptr->FRAGMENT), (pointer)data_addr, frag_ptr->LENGTH); data_addr += frag_ptr->LENGTH; data_length -= frag_ptr->LENGTH; } local_pcb_ptr->FRAGMENTS[0].LENGTH = max_size - data_length; if (info_ptr->READ_CALLBACK_FUNCTION) { (*info_ptr->READ_CALLBACK_FUNCTION)(info_ptr->FD, local_pcb_ptr); } else { _queue_enqueue((QUEUE_STRUCT_PTR)&info_ptr->READ_QUEUE, (QUEUE_ELEMENT_STRUCT_PTR)&local_pcb_ptr->QUEUE); _lwsem_post(&info_ptr->READ_LWSEM); } /* Set the buffer pointer and control bits */ bd_ptr->CONTROL &= IO_PCB_SHM_BUFFER_ALOCATED; _DCACHE_FLUSH_LINE(bd_ptr); /* Update Info structure */ info_ptr->RXNEXT = NEXT_INDEX(info_ptr->RXNEXT, info_ptr->RX_LENGTH); info_ptr->RXENTRIES--; /* Get the next RX buffer descriptor */ bd_ptr = &info_ptr->RX_RING_PTR[info_ptr->RXNEXT]; _DCACHE_INVALIDATE_LINE(bd_ptr); cntrl = bd_ptr->CONTROL; remote_pcb_ptr = (IO_PCB_STRUCT_PTR) _bsp_ptov(bd_ptr->PACKET_PTR); _DCACHE_INVALIDATE_MBYTES(remote_pcb_ptr, sizeof(*remote_pcb_ptr)); num_frags = remote_pcb_ptr->NUMBER_OF_FRAGMENTS; } if (init_ptr->TX_VECTOR == 0) { _io_pcb_shm_tx_isr(handle); } /* Reception successful */ if (!discard) { /* Trigger remote side */ (*init_ptr->INT_TRIGGER)(init_ptr->REMOTE_TX_VECTOR); } _int_enable(); }
void _io_pcb_shm_tx ( /* [IN] the device info */ pointer handle ) { IO_PCB_SHM_INFO_STRUCT_PTR info_ptr; IO_PCB_STRUCT_PTR pcb_ptr; IO_PCB_SHM_BUFFER_STRUCT_PTR bd_ptr; IO_PCB_SHM_INIT_STRUCT_PTR init_ptr; IO_PCB_FRAGMENT_STRUCT_PTR frag_ptr; uint_32 work = FALSE; uint_16 num_frags; info_ptr = (IO_PCB_SHM_INFO_STRUCT_PTR)handle; init_ptr = &info_ptr->INIT; while (TRUE) { _int_disable(); /* Check if queue empty */ if (!_queue_get_size(&info_ptr->WRITE_QUEUE)) { _int_enable(); break; } /* Check if queue empty */ if (!(info_ptr->TXENTRIES)) { _int_enable(); info_ptr->TX_BD_RUNOVER++; break; } /* Get the packet from output queue */ pcb_ptr = (IO_PCB_STRUCT_PTR)((pointer) _queue_dequeue(&info_ptr->WRITE_QUEUE)); /* Get the next buffer descriptor */ bd_ptr = &info_ptr->TX_RING_PTR[info_ptr->TXNEXT]; /* Flush packet */ num_frags = pcb_ptr->NUMBER_OF_FRAGMENTS; for(frag_ptr = (IO_PCB_FRAGMENT_STRUCT_PTR) &(pcb_ptr->FRAGMENTS[0]); num_frags; num_frags--, frag_ptr++) { _DCACHE_FLUSH_MLINES(frag_ptr->FRAGMENT,frag_ptr->LENGTH); frag_ptr->FRAGMENT = _bsp_vtop(frag_ptr->FRAGMENT); } /* Set the buffer descriptor */ bd_ptr->PACKET_PTR = (IO_PCB_STRUCT_PTR) _bsp_vtop(pcb_ptr); bd_ptr->CONTROL = (IO_PCB_SHM_BUFFER_OWN|IO_PCB_SHM_BUFFER_ALOCATED); _DCACHE_FLUSH_LINE(bd_ptr); /* Update Info structure */ info_ptr->TXNEXT = NEXT_INDEX(info_ptr->TXNEXT, info_ptr->TX_LENGTH); info_ptr->TXENTRIES--; work = TRUE; _int_enable(); } if (work) { /* Trigger remote ISR */ (*init_ptr->INT_TRIGGER)(init_ptr->REMOTE_RX_VECTOR); } }
int rec_data(int fd, unsigned char * buffer) { unsigned char addr = 0; unsigned char ctrl = 0; unsigned int dataCount = 0; unsigned char stuffed_buffer[MAX_SIZE]; int i = START_FLAG; STOP = FALSE; while (STOP == FALSE) { unsigned char c = 0; //printf("start while \n"); if (read(fd, &c, 1)) { //printf("received a: %x\n",c); switch (i) { case START_FLAG: //printf("start\n"); if (c == FLAG) i = ADDR; break; case ADDR: //printf("adr\n"); if (c == ADDR_TRANS) { addr = c; i = CTRL; } else if (c != FLAG) { i = START_FLAG; } break; case CTRL: //printf("ctrl\n"); if (c == NEXT_CTRL_INDEX(linklayer.sequenceNumber) || c == CTRL_DISC) { ctrl = c; i = BCC1; } else if (c == FLAG) { i = ADDR; } else { i = FLAG; } break; case BCC1: //printf("bcc1\n"); ; int headerErrorProb = rand() % 100; if (headerErrorProb < linklayer.her) { i = START_FLAG; } else { if (c == (addr ^ ctrl)) { i = DATA; } else if (c == FLAG) { i = ADDR; } else { i = START_FLAG; } } break; case DATA: //printf("data\n"); if (c != FLAG) { stuffed_buffer[dataCount] = c; //printf("stuffed: %x\n",stuffed_buffer[dataCount]); dataCount++; } else { //printf("else\n"); if (ctrl == CTRL_DISC) { printf("send disc\n"); if (send_disc(fd, RECEIVER)) return -1; printf("rec ua\n"); if (rec_ua(fd, RECEIVER)) return -1; linklayer.openLink = 0; return DISCONECTED; } else { //printf("else data lenght\n"); unsigned int dataLength = 0; //printf("data count: %d",dataCount); if ((dataLength = byteDestuffing(stuffed_buffer, dataCount, buffer)) == -1) return -1; unsigned char bcc2_received = buffer[dataLength - 1]; //printf("bcc2 received: %x\n", bcc2_received); unsigned char bcc2 = 0; //printf("bcc2\n"); generate_bcc2(buffer, dataLength - 1, &bcc2); //printf("bcc generated: %x\n",bcc2); int frameErrorProb = rand() % 100; if (frameErrorProb < linklayer.fer) { printf("send rej\n"); send_rej(fd); i = START_FLAG; dataCount = 0; } else { //printf("else bcc2\n"); if (bcc2 == bcc2_received) { printf("same bcc2\n"); if (ctrl != NEXT_CTRL_INDEX(linklayer.sequenceNumber)) { printf("send rr1\n"); send_rr(fd); i = START_FLAG; dataCount = 0; } else { printf("send rr 2\n"); linklayer.sequenceNumber = NEXT_INDEX(linklayer.sequenceNumber); send_rr(fd); return (dataLength - 1); } } else { printf("not the same bcc2\n"); if (ctrl != NEXT_CTRL_INDEX(linklayer.sequenceNumber)) send_rr(fd); else send_rej(fd); i = START_FLAG; dataCount = 0; } } } } break; } } } printf("return\n"); return 0; }
int rec_resp_receiver(int fd, unsigned char * buffer, unsigned int length, unsigned char bcc2) { setAlarm(); unsigned char addr = 0; unsigned char ctrl = 0; int i = START_FLAG; STOP = FALSE; while (STOP == FALSE) { unsigned char c = 0; if (alarmCount >= linklayer.numTransmissions) { printf("EXCEDED NUMBER OF TRIES\n"); close_port_file(fd); return -1; } else if (alarmFlag == 1) { printf("RE-SEND RR!!!\n"); send_data(fd, buffer, length); alarmFlag = 0; alarm(linklayer.timeout); } if (read(fd, &c, 1)) { switch (i) { case START_FLAG: if (c == FLAG) i = ADDR; break; case ADDR: if (c == ADDR_REC_RESP) { addr = c; i = CTRL; } else if (c != FLAG) { i = START_FLAG; } break; case CTRL: if ((c == CTRL_REC_READY(NEXT_INDEX(linklayer.sequenceNumber))) || (c == CTRL_REC_READY(linklayer.sequenceNumber)) || (c == CTRL_REC_REJECT(linklayer.sequenceNumber))) { ctrl = c; i = BCC1; } else if (c == FLAG) { i = ADDR; } else { i = START_FLAG; } break; case BCC1: if (c == (addr ^ ctrl)) { i = END_FLAG; } else if (c == FLAG) { i = ADDR; } else { i = START_FLAG; } break; case END_FLAG: if (c == FLAG) { if (ctrl == CTRL_REC_READY(NEXT_INDEX(linklayer.sequenceNumber))) { alarm(0); STOP = TRUE; } else if (ctrl == CTRL_REC_REJECT(linklayer.sequenceNumber)) { send_data(fd, buffer, length); i = START_FLAG; alarm(linklayer.timeout); } else if (ctrl == CTRL_REC_READY(linklayer.sequenceNumber)) { alarm(0); STOP = TRUE; } else { i = ADDR; } } else { i = START_FLAG; } break; } } } return 0; }