Studio:Transferring Files: Difference between revisions

From STRIDE Wiki
Jump to navigation Jump to search
No edit summary
Line 11: Line 11:
==STRIDE Runtime Payloads==
==STRIDE Runtime Payloads==


If you prefer, you can build file transfer capability into your application using the STRIDE messaging subsystem.  We propose some source code here that can be incorporated into your target application code.  Once incorporated, the interface we define can be invoked from host-based script code to do file transfers to/from the device. The code presented here is presented as sample code.  You should modify it accordingly for your platform.
If you prefer, you can build file transfer capability into your application using the STRIDE messaging subsystem.  We propose some source code here that can be incorporated into your target application code.  Once incorporated, the interface we define can be invoked from host-based script code to do file transfers to/from the device. The code presented here is sample code - you should modify it accordingly for your platform and needs


In this example code, we define a single target function that controls the sending or reading of file data.  The data and final bytes tally are delivered by [[Scl_msg|STRIDE broadcast messages]].  
In this example code, we define a single target function that controls the sending or reading of file data.  The data and final bytes tally are delivered by [[Scl_msg|STRIDE broadcast messages]].  

Revision as of 21:01, 6 October 2008

Most modern devices have some sort of filesystem and it is often necessary to move files between the host platform and the target device during testing. This article briefly reviews some of the options for transferring files to and from your device.

FTP

SCP

netcat

rsync

STRIDE Runtime Payloads

If you prefer, you can build file transfer capability into your application using the STRIDE messaging subsystem. We propose some source code here that can be incorporated into your target application code. Once incorporated, the interface we define can be invoked from host-based script code to do file transfers to/from the device. The code presented here is sample code - you should modify it accordingly for your platform and needs

In this example code, we define a single target function that controls the sending or reading of file data. The data and final bytes tally are delivered by STRIDE broadcast messages.

definitions:

#pragma once
#include <sr.h>

#define FILETRANSFER_DATA_CHUNK 1024*8
#define MAX_FILE_PATH 255
#define FILETRANSFER_BASE_SMID 10

#define BRD_FILEDATA (FILETRANSFER_BASE_SMID+1 | srMT_BRD | srST_RSP_VAL)
#define BRD_FILEDONE (FILETRANSFER_BASE_SMID+2 | srMT_BRD | srST_RSP_VAL)

typedef struct
{
    unsigned char* pData;
    int bytes;
} FileData_t;

typedef struct
{
    unsigned int totalBytes;
} FileDone_t;

typedef enum 
{
    FILETRANSFER_SEND = 0,
    FILETRANSFER_RECEIVE
} TransferType_e;

#ifdef __cplusplus
extern "C" {
#endif

unsigned int transfer_file(TransferType_e type, char* file_path);

#ifdef _SCL
#pragma scl_msg(BRD_FILEDONE, FileDone_t)
#pragma scl_ptr_sized(FileData_t, pData, "RETURN", "PRIVATE", FILETRANSFER_DATA_CHUNK, bytes)
#pragma scl_msg(BRD_FILEDATA, FileData_t)

#pragma scl_function(transfer_file)
#pragma scl_string(transfer_file, file_path, MAX_FILE_PATH)
#endif

#ifdef __cplusplus
}
#endif

implementation:

#include "FileTransfer.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "srconn.h"

unsigned int transfer_file(TransferType_e type, char* file_path)
{
    unsigned int retval = 0;    
    srWORD wSTID        = 0;
    srDWORD dwNID       = 0;
    FILE* fStream       = NULL;
    char openMode[8];

    if (srQueryName("strideIM", &wSTID) != srOK) {
        srPrintError("srQueryName for strideIM failed");
        goto transfer_quit;
    }

    if (srQuerySTID(&dwNID, wSTID) != srOK) {
        srPrintError("srQuerySTID failed");
        goto transfer_quit;
    }

    if ((file_path == NULL) || (strlen(file_path) == 0)) {
        srPrintError("No file provided");
        goto transfer_error;
    }

    if (type == FILETRANSFER_SEND) 
        strcpy(openMode, "rb");
    else if (type == FILETRANSFER_RECEIVE)
        strcpy(openMode, "wb");
    else {
        srPrintError("invalid transfer type");
        goto transfer_error;
    }

    if ((fStream = fopen(file_path, openMode)) == NULL) {
        srPrintError("file open failed");
        goto transfer_error;
    }

    if (type == FILETRANSFER_SEND) {
        // file being sent by target to host
        unsigned char readBuf[FILETRANSFER_DATA_CHUNK];
        while (1) {
            size_t bytesRead = fread(readBuf, sizeof(unsigned char), FILETRANSFER_DATA_CHUNK, fStream);
            if (bytesRead > 0) {
                FileData_t data;
                srWORD wEptr0 = srPTR_EMPTY;
                data.pData = readBuf;
                data.bytes = bytesRead;
                srPtrSetup(wSTID, BRD_FILEDATA, (srWORD)(0), srNULL, bytesRead*sizeof(unsigned char),
                            srMSGDIR_RESPONSE, srPTRDIR_RSP_RET, srPTR_USAGE_PRIVATE, &wEptr0);
                srBroadcast(wSTID, BRD_FILEDATA, (srBYTE*)&data, sizeof(FileData_t));
                retval += bytesRead;
            }

            if (feof(fStream)) {
                break;
            }

            if (ferror(fStream)) {
                srPrintError("file read error");
                break;
            }
        }
    }
    else {
        // file sent by host to target
        srBOOL  bReceiving = srTRUE;
        srSubscribe(wSTID, srBOX_5, srCONNECT_STATUS_B_SMID, srTRUE);
        srSubscribe(wSTID, srBOX_5, BRD_FILEDATA, srTRUE);
        srSubscribe(wSTID, srBOX_5, BRD_FILEDONE, srTRUE);

        while(bReceiving == srTRUE) {
            srDWORD dwMsgInst = 0;
            palDWORD dwEvents = palALL_EVENTS_MASK;
            srBoxInfo_t tBoxInfo;
            palWait(dwNID, &dwEvents);
            if (dwEvents & palSTOP_EVENT)
                break;

            if (srQueryBox(wSTID, srBOX_5, &tBoxInfo) == srOK) {
                srDWORD dwSMIDRead;
                srBYTE  pyMsgBuff[sizeof(FileData_t)];
                srWORD  wMsgSize;
                srWORD  wReadRet = srRead(wSTID,
                                          srBOX_5,
                                          sizeof(pyMsgBuff),
                                          &dwSMIDRead,
                                          pyMsgBuff,
                                          &wMsgSize,
                                          &dwMsgInst);
                switch (dwSMIDRead)
                {
                    case BRD_FILEDATA: {
                        FileData_t* pData = (FileData_t*)pyMsgBuff;
                        size_t bytesWritten = fwrite(pData->pData, sizeof(unsigned char), pData->bytes, fStream);
                        retval += bytesWritten;
                        if (bytesWritten != pData->bytes) {
                            srPrintError("file write error - byte mismatch");
                            bReceiving = srFALSE;
                        }

                        if (ferror(fStream)) {
                            srPrintError("file write error");
                            bReceiving = srFALSE;
                        }

                        break;
                    }
                    case BRD_FILEDONE: {
                        FileDone_t* pData = (FileDone_t*)pyMsgBuff;
                        if (pData->totalBytes != retval) {
                            srPrintError("did not receive expected bytes");
                        }
                        bReceiving = srFALSE;
                        break;
                    }
                    case srCONNECT_STATUS_B_SMID: {
                        srConnectStatusRsp_t* status = (srConnectStatusRsp_t*)pyMsgBuff;
                        if(status->eConnection==srCONNECTION_CLOSED) {
                            srPrintError("srCONNECTION_CLOSED");
                            bReceiving = srFALSE;
                        }
                        break;
                    }
                }
            }
            srReadComplete(wSTID, dwMsgInst);
        }

        srSubscribe(wSTID, srBOX_5, srCONNECT_STATUS_B_SMID, srFALSE);
        srSubscribe(wSTID, srBOX_5, BRD_FILEDATA, srFALSE);
        srSubscribe(wSTID, srBOX_5, BRD_FILEDONE, srFALSE);
    }

    fclose(fStream);
transfer_error:
    if (type == FILETRANSFER_SEND) {
        FileDone_t   doneData;
        doneData.totalBytes = retval;
        srBroadcast(wSTID, BRD_FILEDONE, (srBYTE*)&doneData, sizeof(FileDone_t));
    }
transfer_quit:
    return retval;
}