00001 #ifndef __J2K__TFTP_Packet_CPP__
00002 #define __J2K__TFTP_Packet_CPP__
00003
00004 #include <j2k/Net/TFTP/TFTP_Packet.hpp>
00005
00006
00007 TFTP_Packet::TFTP_Packet()
00008 : pkt( NULL ), pktLength( 0 ) { }
00009
00010
00011 inline void TFTP_Packet::setOpCode( enum OpCode_t op ) {
00012 opCode = (short)op;
00013 }
00014
00015
00016 inline short TFTP_Packet::getOpCode() {
00017 return opCode;
00018 }
00019
00020 void TFTP_Packet::create_RRQ_WRQ()
00021 {
00022 option.rwlock3_templates.read();
00023
00024 long opt = option.Option_templateLength - 2;
00025 size_t sz = option.RRQ_WRQ_templateLength;
00026
00027 if ( opt <= 0 ) opt = 0;
00028 pktLength = sz + opt;
00029 pkt = new char[ pktLength ];
00030
00031 memcpy( pkt, option.RRQ_WRQ_template, sz );
00032 memcpy( pkt, (char*)&opCode, 2 );
00033
00034
00035
00036 if ( opt > 0 ) {
00037 memcpy( pkt + sz, option.Option_template + 2, opt );
00038 }
00039
00040 option.rwlock3_templates.releaseRead();
00041 }
00042
00043 inline void TFTP_Packet::sendRRQ()
00044 {
00045 opCode = 1;
00046 create_RRQ_WRQ();
00047 option.sender->send( pkt, pktLength );
00048 }
00049
00050 inline void TFTP_Packet::sendWRQ()
00051 {
00052 opCode = 2;
00053 create_RRQ_WRQ();
00054 option.sender->send( pkt, pktLength );
00055 }
00056
00057
00058 void TFTP_Packet::createData( short blockNo, char* data, size_t sz )
00059 {
00060 opCode = 3;
00061 block = blockNo;
00062
00063 pktLength = 2 + 2 + sz;
00064 pkt = new char[ pktLength ];
00065
00066 memcpy( pkt, (char*)&opCode, 2 );
00067 memcpy( pkt + 2, (char*)&block, 2 );
00068 if ( sz > 0 ) {
00069 memcpy( pkt + 4, data, sz );
00070 }
00071 }
00072
00073 inline void TFTP_Packet::createData( const char* rawData, size_t sz )
00074 {
00075 if ( pkt == NULL ) pkt = new char[ sz + 1 ];
00076 pktLength = sz;
00077 memcpy( pkt, rawData, sz );
00078 }
00079
00080 inline void TFTP_Packet::sendData( short blockNo, char* data, size_t sz )
00081 {
00082 if ( sz > 0 ) {
00083 createData( blockNo, data, sz );
00084 pktLength = 4 + sz;
00085 } else {
00086 pktLength = 4;
00087 }
00088 option.sender->send( pkt, pktLength );
00089 }
00090
00091 inline void TFTP_Packet::send() {
00092 printf( "Sending Data: %d, %u", pkt, pktLength );
00093 option.sender->send( pkt, pktLength );
00094 }
00095
00096 void TFTP_Packet::createAck( short blockNo )
00097 {
00098 opCode = 4;
00099 block = blockNo;
00100
00101 pktLength = 2 + 2;
00102 pkt = new char[ pktLength ];
00103
00104 memcpy( pkt, (char*)&opCode, 2 );
00105 memcpy( pkt + 2, (char*)&block, 2 );
00106 }
00107
00108 inline void TFTP_Packet::sendAck( short blockNo )
00109 {
00110 createAck( blockNo );
00111 option.sender->send( pkt, pktLength );
00112 }
00113
00114 void TFTP_Packet::createError( enum TFTP_errcode_t e, const char* errmsg = "" )
00115 {
00116 opCode = 5;
00117 err = (short)e;
00118
00119 if ( errorMsg != NULL ) delete [] errorMsg;
00120 errorMsg = new char[ 200 ];
00121
00122 memset( errorMsg, 0, 200 );
00123
00124 const char* s = TFTP_errmsg[ opCode ];
00125 size_t len2 = strlen( s );
00126
00127 size_t len = strlen( errmsg );
00128 memcpy( errorMsg, errmsg, len );
00129 errorMsg[ len ] = '\n';
00130 memcpy( errorMsg+len+1, s, len2 );
00131
00132 size_t sz = len + len2 + 1;
00133 errorMsg[ sz ] = '\0';
00134
00135 pktLength = 2 + 2 + sz;
00136 pkt = new char[ pktLength ];
00137
00138 memcpy( pkt, (char*)&opCode, 2 );
00139 memcpy( pkt + 2, (char*)&err, 2 );
00140 memcpy( pkt + 4, (char*)errorMsg, sz );
00141 }
00142
00143 inline void TFTP_Packet::sendError( enum TFTP_errcode_t e, const char* errmsg = "" )
00144 {
00145 createError( e, errmsg );
00146 option.sender->send( pkt, pktLength );
00147 }
00148
00149 inline char* TFTP_Packet::getErrorMsg()
00150 {
00151 return errorMsg;
00152 }
00153
00154 void TFTP_Packet::createOAck()
00155 {
00156 opCode = 6;
00157
00158 option.rwlock3_templates.read();
00159
00160 size_t opt = option.Option_templateLength - 2;
00161
00162 pktLength = opt + 2;
00163 pkt = new char[ pktLength ];
00164
00165
00166
00167 if ( opt > 0 ) {
00168 memcpy( pkt, option.Option_template + 2, opt );
00169 }
00170
00171 memcpy( pkt, (char*)&opCode, 2 );
00172
00173 option.rwlock3_templates.releaseRead();
00174 }
00175
00176 inline void TFTP_Packet::sendOAck()
00177 {
00178 createOAck();
00179 option.sender->send(pkt,pktLength);
00180 }
00181
00182
00183 inline double TFTP_Packet::getTimeStamp() {
00184 return timestamp;
00185 }
00186
00187 inline double TFTP_Packet::getID() {
00188 return block;
00189 }
00190
00191 inline void TFTP_Packet::setTimeStamp( double t ) {
00192 timestamp = ceil( t );
00193 }
00194
00195 inline char* TFTP_Packet::getData() {
00196 return (char*)( pkt + 4 );
00197 }
00198
00199 short TFTP_Packet::getBlockNo() {
00200 short val;
00201 memcpy( (char*)(&val), (pkt+2), 2 );
00202
00203 return val;
00204 }
00205
00206 inline size_t TFTP_Packet::getpktLength() {
00207 return pktLength;
00208 }
00209
00210 #endif