error_t httpSendResponse(HttpConnection *connection, const char_t *uri) { #if (HTTP_SERVER_FS_SUPPORT == ENABLED) error_t error; uint32_t length; size_t n; FsFile *file; //Retrieve the full pathname httpGetAbsolutePath(connection, uri, connection->buffer, HTTP_SERVER_BUFFER_SIZE); //Retrieve the size of the specified file error = fsGetFileSize(connection->buffer, &length); //The specified URI cannot be found? if(error) return ERROR_NOT_FOUND; //Open the file for reading file = fsOpenFile(connection->buffer, FS_FILE_MODE_READ); //Failed to open the file? if(!file) return ERROR_NOT_FOUND; #else error_t error; size_t length; uint8_t *data; //Retrieve the full pathname httpGetAbsolutePath(connection, uri, connection->buffer, HTTP_SERVER_BUFFER_SIZE); //Get the resource data associated with the URI error = resGetData(connection->buffer, &data, &length); //The specified URI cannot be found? if(error) return error; #endif //Format HTTP response header connection->response.statusCode = 200; connection->response.contentType = mimeGetType(uri); connection->response.chunkedEncoding = FALSE; connection->response.contentLength = length; //Send the header to the client error = httpWriteHeader(connection); //Any error to report? if(error) { #if (HTTP_SERVER_FS_SUPPORT == ENABLED) //Close the file fsCloseFile(file); #endif //Return status code return error; } #if (HTTP_SERVER_FS_SUPPORT == ENABLED) //Send response body while(length > 0) { //Limit the number of bytes to read at a time n = MIN(length, HTTP_SERVER_BUFFER_SIZE); //Read data from the specified file error = fsReadFile(file, connection->buffer, n, &n); //End of input stream? if(error) break; //Send data to the client error = httpWriteStream(connection, connection->buffer, n); //Any error to report? if(error) break; //Decrement the count of remaining bytes to be transferred length -= n; } //Close the file fsCloseFile(file); //Successful file transfer? if(length == 0 && error == ERROR_END_OF_STREAM) { //Properly close the output stream error = httpCloseStream(connection); } #else //Send response body error = httpWriteStream(connection, data, length); //Any error to report? if(error) return error; //Properly close output stream error = httpCloseStream(connection); #endif //Return status code return error; }
void ftpServerSendData(FtpServerContext *context, FtpClientConnection *connection) { error_t error; size_t n; //Any data waiting for transmission? if(connection->bufferLength > 0) { //Send more data error = socketSend(connection->dataSocket, connection->buffer + connection->bufferPos, connection->bufferLength, &n, 0); //Failed to send data? if(error != NO_ERROR && error != ERROR_TIMEOUT) { //Close the data connection ftpServerCloseDataConnection(connection); //Release previously allocated resources if(connection->file != NULL) { fsCloseFile(connection->file); connection->file = NULL; } if(connection->dir != NULL) { fsCloseDir(connection->dir); connection->dir = NULL; } //Back to idle state connection->controlState = FTP_CONTROL_STATE_IDLE; //Transfer status strcpy(connection->response, "451 Transfer aborted\r\n"); //Debug message TRACE_DEBUG("FTP server: %s", connection->response); //Number of bytes in the response buffer connection->responseLength = strlen(connection->response); connection->responsePos = 0; //Exit immediately return; } //Advance data pointer connection->bufferPos += n; //Number of bytes still available in the buffer connection->bufferLength -= n; } //Empty transmission buffer? if(connection->bufferLength == 0) { //File transfer in progress? if(connection->controlState == FTP_CONTROL_STATE_RETR) { //Read more data error = fsReadFile(connection->file, connection->buffer, FTP_SERVER_BUFFER_SIZE, &n); //End of stream? if(error) { //Close file fsCloseFile(connection->file); connection->file = NULL; //Wait for all the data to be transmitted and acknowledged connection->dataState = FTP_DATA_STATE_WAIT_ACK; //Exit immediately return; } } //Directory listing in progress? else if(connection->controlState == FTP_CONTROL_STATE_LIST) { uint_t perm; time_t currentTime; time_t modified; char_t *path; FsDirEntry dirEntry; //Read a new entry in the directory error = fsReadDir(connection->dir, &dirEntry); //End of stream? if(error) { //Close directory fsCloseDir(connection->dir); connection->dir = NULL; //Wait for all the data to be transmitted and acknowledged connection->dataState = FTP_DATA_STATE_WAIT_ACK; //Exit immediately return; } //Point to the scratch buffer path = connection->buffer; //Get the pathname of the directory being listed strcpy(path, connection->path); //Retrieve the full pathname pathCombine(path, dirEntry.name, FTP_SERVER_MAX_PATH_LEN); pathCanonicalize(path); //Get permissions for the specified file perm = ftpServerGetFilePermissions(context, connection, path); //Enforce access rights if(perm & FTP_FILE_PERM_LIST) { //Format links, owner, group and size fields n = sprintf(connection->buffer, "---------- 1 owner group %10" PRIu32, dirEntry.size); //Check whether the current entry is a directory if(dirEntry.attributes & FS_FILE_ATTR_DIRECTORY) connection->buffer[0] = 'd'; //Read access? if(perm & FTP_FILE_PERM_READ) { connection->buffer[1] = 'r'; connection->buffer[4] = 'r'; connection->buffer[7] = 'r'; } //Write access if(perm & FTP_FILE_PERM_WRITE) { connection->buffer[2] = 'w'; connection->buffer[5] = 'w'; connection->buffer[8] = 'w'; } //Get current time currentTime = getCurrentUnixTime(); //Get modification time modified = convertDateToUnixTime(&dirEntry.modified); //Check whether the modification time is within the previous 180 days if(currentTime > modified && currentTime < (modified + FTP_SERVER_180_DAYS)) { //The format of the date/time field is Mmm dd hh:mm n += sprintf(connection->buffer + n, " %s %02" PRIu8 " %02" PRIu8 ":%02" PRIu8, months[MIN(dirEntry.modified.month, 12)], dirEntry.modified.day, dirEntry.modified.hours, dirEntry.modified.minutes); } else { //The format of the date/time field is Mmm dd yyyy n += sprintf(connection->buffer + n, " %s %02" PRIu8 " %04" PRIu16, months[MIN(dirEntry.modified.month, 12)], dirEntry.modified.day, dirEntry.modified.year); } //Append filename n += sprintf(connection->buffer + n, " %s\r\n", dirEntry.name); //Debug message TRACE_DEBUG("FTP server: %s", connection->buffer); } else { //Insufficient access rights n = 0; } } //Invalid state? else { //The FTP server has encountered a critical error ftpServerCloseConnection(context, connection); //Exit immediately return; } //Number of bytes in the buffer connection->bufferPos = 0; connection->bufferLength = n; } }
errc tapLoadFile(tFileSystemDirEntry *dir) { unsigned long addr, targetAddr; unsigned char pole[3]; unsigned char *ind; unsigned char data[512]; unsigned char state; unsigned int block_length, min; unsigned int memInd, sector; errc err; targetAddr = 0x80000; sector=0; state = 0; addr = 0; //prenesu snapshot do pameti. (dir->size) while (addr < (dir->size)) { //vypocitam si index do pole s daty. Pole je velke 512 bajtu memInd = addr & 0x1FF; //prectu odpovidajici sektor v souboru if (memInd == 0) { if ((err = fsReadFile(dir->cluster, sector, data)) != ERR_OK) return err; sector++; dmaSetDestAddr(targetAddr); dmaSetConfig(DMA_INC_DST | DMA_INC_SRC); } switch(state) { //DATA BLOCK case 0: //DATA LENGTH lsb block_length = data[memInd]; addr++; state = 1; break; case 1: //DATA LENGTH msb block_length |= (((unsigned int)data[memInd]) << 8); addr++; state = 2; break; //TAPE DATA case 2: //TAPE DATA min = 512 - memInd; min = (block_length > min ? min : block_length); //nastavim DMA radic dmaSetSrcAddr(swAddr2hwAddr(((unsigned long)data)+memInd)); dmaTransfer(min); targetAddr += min; block_length -= min; addr += min; if (block_length==0) state = 0; break; } } //pripravim ukazatel DMA na zacatek tape dat. ROMka pak muze cist kazetu pekne od zacatku dmaSetSrcAddr(0x80000); dmaSetConfig(DMA_INC_SRC); //spustim aplikaci ind = pole; ind += taskSetPC(ind,0,0); ind--; taskRun(ind,pole); return ERR_OK; }
void play_from_file(INT choose,INT ch) { INT hFile; INT nReadBytes; INT nTime0; INT nErr; INT8 bAsciiFileName [20]; INT8 bUnicodeFileName [40]; INT ntemp,nVol=20 ; INT nSPToggle=0; INT nHPToggle=0; _uPcmQHead = _uPcmQTail = 0; strcpy(bAsciiFileName , "c:\\record.pcm"); fsAsciiToUnicode(bAsciiFileName, bUnicodeFileName, TRUE); hFile = fsOpenFile(bUnicodeFileName, NULL, OP_READ); if (hFile < 0) { printf("Can't open playback file0x%x!\n",hFile); //return; } #if defined (TEST_WM8978) /* for eCos version audio lib*/ #if 0 if (choose==32000)//8.192Mhz { outpw(REG_APLLCON, 0x6529); outpw(REG_CLKDIV0, (inpw(REG_CLKDIV0) & 0xFF0FFFFF) | 0x500000); } else if (choose%8000==0 || choose%12000==0){//12.288Mhz outpw(REG_APLLCON, 0x6529); outpw(REG_CLKDIV0, (inpw(REG_CLKDIV0) & 0xFF0FFFFF) | 0x300000); } else if (choose%11025==0){//11.289Mhz outpw(REG_APLLCON, 0x652f); outpw(REG_CLKDIV0, (inpw(REG_CLKDIV0) & 0xFF0FFFFF) | 0x400000); } #else if (choose%8000==0 || choose%12000==0){//24.576Mhz outpw(REG_APLLCON, 0x6529); outpw(REG_CLKDIV0, (inpw(REG_CLKDIV0) & 0xFF0FFFFF) | 0x100000); } else if (choose%11025==0){//22.579Mhz outpw(REG_APLLCON, 0x642d); outpw(REG_CLKDIV0, (inpw(REG_CLKDIV0) & 0xFF0FFFFF) | 0x200000); } #endif #endif /* read PCM data to PCM buffer */ printf("Read %d KB to PCM data buffer...\n", PCM_QUEUE_LEN/1024); nErr = fsReadFile(hFile, _pucPcmQueue, 256*1024, &nReadBytes); if (nErr<0) printf("err num=%d\n",nErr); //memset(_pucPcmQueue,0,PCM_QUEUE_LEN); printf("OK\n"); audioStartPlay(play_callback, choose, ch); //tiaic31StartPlay(play_callback, choose, channels,format); audioSetPlayVolume(nVol,nVol); ntemp = nTime0 = sysGetTicks(TIMER1); while (1) { if (sysGetTicks(TIMER1) - nTime0 >= 100) { nTime0 = sysGetTicks(TIMER1); printf("H=%d, T=%d\n", _uPcmQHead/1024, _uPcmQTail/1024); } if ((_uPcmQTail > _uPcmQHead) || ((_uPcmQTail < _uPcmQHead) && (_uPcmQHead - _uPcmQTail > 64*1024))) { fsReadFile(hFile, &_pucPcmQueue[_uPcmQTail], 64*1024, &nReadBytes); if (nReadBytes > 0) _uPcmQTail = (_uPcmQTail + nReadBytes) % PCM_QUEUE_LEN; if (sysGetTicks(TIMER1) - ntemp >=1000) break; } if (inpb(REG_COM_LSR) & 0x01) /* check key press */ { CHAR cmd = inpb(REG_COM_RX); if (cmd=='1') { if (--nVol<=0) nVol=0; audioSetPlayVolume(nVol,nVol); printf("vol=%d\n",nVol); }else if (cmd=='2') { if (++nVol>=31) nVol=31; audioSetPlayVolume(nVol,nVol); printf("vol=%d\n",nVol); }else if (cmd=='3') { if (nSPToggle) { audioSelectOutputPath(OUT_PATH_SP,TRUE); nSPToggle = 0; }else { audioSelectOutputPath(OUT_PATH_SP,FALSE); nSPToggle = 1; } } else if (cmd=='4') { if (nHPToggle) { audioSelectOutputPath(OUT_PATH_HP,TRUE); nHPToggle = 0; }else { audioSelectOutputPath(OUT_PATH_HP,FALSE); nHPToggle = 1; } } } } fsCloseFile(hFile); audioStopPlay(); }
error_t ssiExecuteScript(HttpConnection *connection, const char_t *uri, uint_t level) { error_t error; size_t length; #if (HTTP_SERVER_FS_SUPPORT == ENABLED) bool_t more; uint_t pos; uint_t n; char_t *buffer; FsFile *file; #else uint_t i; uint_t j; char_t *data; #endif //Recursion limit exceeded? if(level >= HTTP_SERVER_SSI_MAX_RECURSION) return NO_ERROR; //Retrieve the full pathname httpGetAbsolutePath(connection, uri, connection->buffer, HTTP_SERVER_BUFFER_SIZE); #if (HTTP_SERVER_FS_SUPPORT == ENABLED) //Open the file for reading file = fsOpenFile(connection->buffer, FS_FILE_MODE_READ); //Failed to open the file? if(!file) return ERROR_NOT_FOUND; //Allocate a memory buffer buffer = osAllocMem(HTTP_SERVER_BUFFER_SIZE); //Failed to allocate memory? if(!buffer) { //Close the file fsCloseFile(file); //Report an error return ERROR_OUT_OF_MEMORY; } #else //Get the resource data associated with the URI error = resGetData(connection->buffer, (uint8_t **) &data, &length); //The specified URI cannot be found? if(error) return error; #endif //Send the HTTP response header before executing the script if(!level) { //Format HTTP response header connection->response.statusCode = 200; connection->response.contentType = mimeGetType(uri); connection->response.chunkedEncoding = TRUE; //Send the header to the client error = httpWriteHeader(connection); //Any error to report? if(error) { #if (HTTP_SERVER_FS_SUPPORT == ENABLED) //Close the file fsCloseFile(file); //Release memory buffer osFreeMem(buffer); #endif //Return status code return error; } } #if (HTTP_SERVER_FS_SUPPORT == ENABLED) //Point to the beginning of the buffer pos = 0; length = 0; //This flag indicates whether data should be read more = TRUE; //Parse the specified file while(1) { //Read more data if needed if(more) { //Read data from the specified file error = fsReadFile(file, buffer + pos + length, HTTP_SERVER_BUFFER_SIZE - (pos + length), &n); //End of input stream? if(error) { //Purge data buffer error = httpWriteStream(connection, buffer + pos, length); //Exit immediately break; } //Adjust the length of the buffer length += n; //Clear flag more = FALSE; } //Search for any SSI tags error = ssiSearchTag(buffer + pos, length, "<!--#", 5, &n); //Full match? if(error == NO_ERROR) { //Send the part of the file that precedes the tag error = httpWriteStream(connection, buffer + pos, n); //Failed to send data? if(error) break; //Advance data pointer pos += n; length -= n; //Search for the comment terminator error = ssiSearchTag(buffer + pos + 5, length - 5, "-->", 3, &n); //Full match? if(error == NO_ERROR) { //Advance data pointer over the opening identifier pos += 5; length -= 5; //Process SSI directive error = ssiProcessCommand(connection, buffer + pos, n, uri, level); //Any error to report? if(error) break; //Advance data pointer over the SSI tag pos += n + 3; length -= n + 3; } //No match or partial match? else { if(pos > 0) { //Move the remaining bytes to the start of the buffer memmove(buffer, buffer + pos, length); //Rewind to the beginning of the buffer pos = 0; //More data are needed more = TRUE; } else { //Send data to the client error = httpWriteStream(connection, buffer + pos, length); //Any error to report? if(error) break; //Rewind to the beginning of the buffer pos = 0; length = 0; //More data are needed more = TRUE; } } } //Partial match? else if(error == ERROR_PARTIAL_MATCH) { //Send the part of the file that precedes the tag error = httpWriteStream(connection, buffer + pos, n); //Failed to send data? if(error) break; //Advance data pointer pos += n; length -= n; //Move the remaining bytes to the start of the buffer memmove(buffer, buffer + pos, length); //Rewind to the beginning of the buffer pos = 0; //More data are needed more = TRUE; } //No match? else { //Send data to the client error = httpWriteStream(connection, buffer + pos, length); //Any error to report? if(error) break; //Rewind to the beginning of the buffer pos = 0; length = 0; //More data are needed more = TRUE; } } //Close the file fsCloseFile(file); //Release memory buffer osFreeMem(buffer); //Properly close the output stream if(!level && error == NO_ERROR) error = httpCloseStream(connection); #else //Parse the specified file while(length > 0) { //Search for any SSI tags error = ssiSearchTag(data, length, "<!--#", 5, &i); //Opening identifier found? if(!error) { //Search for the comment terminator error = ssiSearchTag(data + i + 5, length - i - 5, "-->", 3, &j); } //Check whether a valid SSI tag has been found? if(!error) { //Send the part of the file that precedes the tag error = httpWriteStream(connection, data, i); //Failed to send data? if(error) return error; //Advance data pointer over the opening identifier data += i + 5; length -= i + 5; //Process SSI directive error = ssiProcessCommand(connection, data, j, uri, level); //Any error to report? if(error) return error; //Advance data pointer over the SSI tag data += j + 3; length -= j + 3; } else { //Send the rest of the file error = httpWriteStream(connection, data, length); //Failed to send data? if(error) return error; //Advance data pointer data += length; length = 0; } } //Properly close the output stream if(!level) error = httpCloseStream(connection); #endif //Return status code return error; }
error_t ssiProcessIncludeCommand(HttpConnection *connection, const char_t *tag, size_t length, const char_t *uri, uint_t level) { error_t error; char_t *separator; char_t *attribute; char_t *value; char_t *path; char_t *p; //Discard invalid SSI directives if(length < 7 || length >= HTTP_SERVER_BUFFER_SIZE) return ERROR_INVALID_TAG; //Skip the SSI include command (7 bytes) memcpy(connection->buffer, tag + 7, length - 7); //Ensure the resulting string is NULL-terminated connection->buffer[length - 7] = '\0'; //Check whether a separator is present separator = strchr(connection->buffer, '='); //Separator not found? if(!separator) return ERROR_INVALID_TAG; //Split the tag *separator = '\0'; //Get attribute name and value attribute = strTrimWhitespace(connection->buffer); value = strTrimWhitespace(separator + 1); //Remove leading simple or double quote if(value[0] == '\'' || value[0] == '\"') value++; //Get the length of the attribute value length = strlen(value); //Remove trailing simple or double quote if(length > 0) { if(value[length - 1] == '\'' || value[length - 1] == '\"') value[length - 1] = '\0'; } //Check the length of the filename if(strlen(value) > HTTP_SERVER_URI_MAX_LEN) return ERROR_INVALID_TAG; //The file parameter defines the included file as relative to the document path if(!strcasecmp(attribute, "file")) { //Allocate a buffer to hold the path to the file to be included path = osAllocMem(strlen(uri) + strlen(value) + 1); //Failed to allocate memory? if(!path) return ERROR_OUT_OF_MEMORY; //Copy the path identifying the script file being processed strcpy(path, uri); //Search for the last slash character p = strrchr(path, '/'); //Remove the filename from the path if applicable if(p) strcpy(p + 1, value); else strcpy(path, value); } //The virtual parameter defines the included file as relative to the document root else if(!strcasecmp(attribute, "virtual")) { //Copy the absolute path path = strDuplicate(value); //Failed to duplicate the string? if(!path) return ERROR_OUT_OF_MEMORY; } //Unknown parameter... else { //Report an error return ERROR_INVALID_TAG; } //Use server-side scripting to dynamically generate HTML code? if(httpCompExtension(value, ".stm") || httpCompExtension(value, ".shtm") || httpCompExtension(value, ".shtml")) { //SSI processing (Server Side Includes) error = ssiExecuteScript(connection, path, level + 1); } else { #if (HTTP_SERVER_FS_SUPPORT == ENABLED) FsFile *file; //Retrieve the full pathname httpGetAbsolutePath(connection, path, connection->buffer, HTTP_SERVER_BUFFER_SIZE); //Open the file for reading file = fsOpenFile(connection->buffer, FS_FILE_MODE_READ); //Successful operation? if(file) { //Send the contents of the requested file while(1) { //Read data from the specified file error = fsReadFile(file, connection->buffer, HTTP_SERVER_BUFFER_SIZE, &length); //End of input stream? if(error) break; //Send data to the client error = httpWriteStream(connection, connection->buffer, length); //Any error to report? if(error) break; } //Close the file fsCloseFile(file); //Successful file transfer? if(error == ERROR_END_OF_STREAM) error = NO_ERROR; } else { //The specified URI cannot be found error = ERROR_NOT_FOUND; } #else uint8_t *data; //Retrieve the full pathname httpGetAbsolutePath(connection, path, connection->buffer, HTTP_SERVER_BUFFER_SIZE); //Get the resource data associated with the file error = resGetData(connection->buffer, &data, &length); //Send the contents of the requested file if(!error) error = httpWriteStream(connection, data, length); #endif } //Cannot found the specified resource? if(error == ERROR_NOT_FOUND) error = ERROR_INVALID_TAG; //Release previously allocated memory osFreeMem(path); //return status code return error; }