00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "l1394_transaction.h"
00019 #include "l1394_session.h"
00020 #include "l1394_frame.h"
00021 #include <errno.h>
00022
00023 using namespace std;
00024
00025 namespace L1394 {
00026 namespace internal{
00027 Transaction::Transaction(raw1394handle_t default_handle){
00028 this->default_handle = default_handle;
00029
00030 }
00031
00032 Transaction::~Transaction() {
00033
00034 }
00035
00036 int Transaction::read(const u_int64_t address, Quadlet *q, const u_int32_t node_id ) const
00037 {
00038 Quadlet t;
00039
00040 int response_code = 0;
00041 int count = 16;
00042 quadlet_t buffer = 0;
00043
00044 while( count-- )
00045 {
00046 if (safe_mode)
00047 {
00048 delay(delay_value);
00049 }
00050
00051 response_code = raw1394_read(default_handle, 0xffc0 | node_id,address , 4, &buffer);
00052
00053 if (!response_code) {
00054 buffer = ntohl(buffer);
00055 q->fromInt(buffer);
00056 return L1394_SUCCESS;
00057 } else
00058 if (errno != EAGAIN)
00059 return L1394_FAILED;
00060
00061 if (count < 5)
00062 {
00063 SMessage::getInstance()->warningStream() << "problem with reading -> increase delay" << endl;
00064 delay(delay_value);
00065 }
00066 if (count <= 0)
00067 {
00068 SMessage::getInstance()->errorStream() << "Node > Stop reading " << endl;
00069
00070
00071 SMessage::getInstance()->errorStream() << "Node > from address: 0x" << hex << address << dec << endl;
00072 return L1394_FAILED;
00073 }
00074 }
00075
00076 buffer = ntohl(buffer);
00077 q->fromInt(buffer);
00078
00079 return L1394_SUCCESS;
00080 }
00081
00082 int Transaction::write(const u_int64_t address,const Quadlet& buffer,const u_int32_t node_id) const
00083 {
00084 quadlet_t tmp = htonl(buffer.toInt());
00085 int response_code = 0;
00086 int count = 16;
00087
00088 SMessage::getInstance()->debugStream() << "Node > Try to send 0x" << buffer << "to node "<< node_id << endl;
00089 SMessage::getInstance()->debugStream() << "Node > Sending 0x" << hex << tmp << dec << "to node "<< node_id << endl<<endl;
00090
00091 while ( count--)
00092 {
00093 if (safe_mode)
00094 delay(delay_value);
00095
00096 response_code = raw1394_write(default_handle, 0xffc0 | node_id,address , 4, &tmp);
00097
00098 if (!response_code || (errno != EAGAIN)) {
00099 return L1394_SUCCESS;
00100 }
00101
00102 if (count < 5)
00103 {
00104 SMessage::getInstance()->warningStream()<< "Problem with writing -> increasing delay" << endl;
00105 delay(delay_value);
00106 }
00107
00108 if (count <= 0)
00109 {
00110 SMessage::getInstance()->errorStream() << "Node > Stop reading " << endl;
00111 SMessage::getInstance()->errorStream() << "Node > with error : " << response_code << endl;
00112 return L1394_FAILED;
00113 }
00114 }
00115
00116 if(count < 16)
00117 SMessage::getInstance()->debugStream() << "Node > sending success" << endl;
00118
00119 return L1394_SUCCESS;
00120 }
00121
00122 int Transaction::lock(const u_int64_t address,const Quadlet& data,const unsigned int extcode, const Quadlet& argument, Quadlet* result, const u_int32_t node_id) const
00123 {
00124 int response_code = 0;
00125 int count = 16;
00126 quadlet_t result_t = 0;
00127
00128 while( count-- )
00129 {
00130 if (safe_mode)
00131 {
00132 delay(delay_value);
00133 }
00134
00135 response_code = raw1394_lock(default_handle, 0xffc0 | node_id, address, extcode, htonl(data.toInt()), htonl(argument.toInt()),&result_t);
00136 if (!response_code) {
00137 result_t = ntohl(result_t);
00138 result->fromInt(result_t);
00139 return L1394_SUCCESS;
00140 } else
00141 if (errno != EAGAIN)
00142 return L1394_FAILED;
00143
00144
00145
00146
00147 if (count < 5)
00148 {
00149 SMessage::getInstance()->warningStream() << "Node > Problem with lock -> increase delay" << endl;
00150 sleep(1);
00151 }
00152 if (count <= 0)
00153 {
00154 SMessage::getInstance()->errorStream() << "Node > Stop reading " << endl;
00155 SMessage::getInstance()->errorStream() << "Node > with error : 0x" << hex << response_code << dec << endl;
00156 return L1394_FAILED;
00157 }
00158 }
00159
00160 result->fromInt(ntohl(result_t));
00161 return L1394_SUCCESS;
00162 }
00163
00164 Quadlet Transaction::send(const Quadlet& q, const u_int32_t node_id) const
00165 {
00166
00167 int e, retval;
00168 int tmp = 0;
00169
00170 struct pollfd pfd;
00171
00172 tmp = q.toInt();
00173 tmp = htonl(tmp);
00174
00175 raw1394_set_fcp_handler(default_handle, L1394FcpHandler);
00176 raw1394_start_fcp_listen(default_handle);
00177
00178 if((e=raw1394_write(default_handle,0xffc0 |node_id, FCP_COMMAND_ADDR , 4,(quadlet_t*) &tmp)) < 0)
00179 SMessage::getInstance()->errorStream()<< "FcpNode >" << e<<" writing FCP register"<< endl;
00180
00181 pfd.fd = raw1394_get_fd(default_handle);
00182 pfd.events = POLLIN;
00183 pfd.revents = 0;
00184 while (1)
00185 {
00186 if ((retval=poll(&pfd, 1, 10)) < 1)
00187 break;
00188 raw1394_loop_iterate(default_handle);
00189 }
00190
00191 if (retval < 0)
00192 SMessage::getInstance()->errorStream()<< "FcpNode > poll failed" << endl;
00193
00194 Quadlet my_response;
00195
00196 my_response = response_block->getQuadlet(0);
00197
00198 return my_response;
00199 }
00200
00201
00202 QArray Transaction::send(const QArray& value, const u_int32_t node_id) const
00203 {
00204 int e, retval;
00205
00206 struct pollfd pfd;
00207
00208 u_int32_t tmp[value.getSize()];
00209 value.toIntArray(tmp);
00210
00211 SMessage::getInstance()->debugStream() << "FcpNode > sending " << endl << value <<endl;
00212
00213 for (int i = 0; i<value.getSize(); i++)
00214 tmp[i] = htonl(tmp[i]);
00215
00216 raw1394_set_fcp_handler(default_handle, L1394FcpHandler);
00217 raw1394_start_fcp_listen(default_handle);
00218
00219
00220 if((e=raw1394_write(default_handle,0xffc0 |node_id, FCP_COMMAND_ADDR , value.getSize()*4,(quadlet_t*) tmp)) < 0)
00221 SMessage::getInstance()->errorStream() << "FcpNode > Error " << e<<" writing FCP register\n"<< endl;
00222
00223 pfd.fd = raw1394_get_fd(default_handle);
00224 pfd.events = POLLIN;
00225 pfd.revents = 0;
00226
00227 while (1) {
00228 if ((retval=poll(&pfd, 1, 10)) < 1)
00229 break;
00230 raw1394_loop_iterate(default_handle);
00231 }
00232
00233 if (retval < 0)
00234 SMessage::getInstance()->errorStream() << "FcpNode > FcpNode > poll failed " << endl;
00235
00236 SMessage::getInstance()->debugStream() << "FcpNode > FcpNode > " << response_block->getQuadlet(1) << endl;
00237
00238 if (response_block == NULL) {
00239 SMessage::getInstance()->warningStream()<< "FcpNode > FcpNode > Get no correct response " << endl;
00240 response_block = new QArray(0);
00241 }
00242
00243 return *response_block;
00244 }
00245
00246
00247 int Transaction::L1394FcpHandler(raw1394handle_t , nodeid_t nodeid, int ,
00248 size_t length, unsigned char *data)
00249 {
00250
00251 if (response_block != NULL) {
00252 delete response_block;
00253 response_block = NULL;
00254 }
00255
00256 SMessage::getInstance()->debugStream()<< "FcpNode > got fcp response form node "
00257 << (nodeid & 0x3f) << " of " << length << " bytes " << endl;
00258
00259 QArray *tmp_array = new QArray(length/4);
00260 if (data != NULL)
00261 for(unsigned int i = 0; i<length; i++)
00262 tmp_array->setByte(i, data[i]);
00263
00264 response_block = tmp_array;
00265 SMessage::getInstance()->debugStream() << "FcpNode > FcpNode "<<endl<< *response_block << endl;
00266
00267 return 0;
00268 }
00269
00270 void Transaction::delay(int msecs) {
00271 timeval tv;
00272
00273 tv.tv_sec = 0;
00274 tv.tv_usec = 1000*msecs;
00275
00276 select(0, NULL, NULL, NULL, &tv);
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 QArray* Transaction::response_block = 0;
00294 bool Transaction::safe_mode = false;
00295 int Transaction::delay_value = DELAY;
00296
00297 }
00298 }