packetHandleHost.c

00001 /*
00002   パケット操作
00003   Satofumi KAMIMURA
00004   $Id$
00005 */
00006 
00007 #include "packetHandleHost.h"
00008 #ifdef __cplusplus
00009 #include "runCtrl.h"
00010 #else
00011 #include "connect_device.h"
00012 #define ConnectionDevice int
00013 #endif
00014 
00015 
00016 enum {
00017   SEND_PACKET_SIZE = 512,
00018   TIMEOUT_SHIFT = 3,
00019 };
00020 
00021 
00022 // !!! 複数のクライアントを扱うようになったら、そのときに変更する
00023 static int RetryTimes = 3;
00024 void set_runRetryTimes(int times) {
00025   RetryTimes = times;
00026 }
00027 
00028 static int RecvTimeout = -1;
00029 void set_runRecvTimeout(int timeout) {
00030   RecvTimeout = timeout;
00031 }
00032 
00033 
00034 
00035 static void sendRetryPacket(ConnectionDevice* con,
00036                             const char* send_packet, int send_size) {
00037 #ifdef __cplusplus
00038   con->send(send_packet, send_size);
00039 #else
00040   device_send(*con, send_packet, send_size);
00041 #endif
00042 }
00043 
00044 
00045 int waitPacketResponse(ConnectionDevice* con, runCtrl_t* tbl,
00046                        char* send_packet, int send_size,
00047                        int unique_id) {
00048   enum {
00049     WaitStartByte,
00050     WaitHeaderRecv,
00051     WaitPacketRecv,
00052     RecvCompleted,
00053     SendRetry,
00054   };
00055   int timeout;
00056   int state = SendRetry;
00057   int retry_times = 0;
00058   char recv_buffer[SEND_PACKET_SIZE];
00059   int filled = 0;
00060   int require_size = NODE_ACCESS_PACKET_HEADER_SIZE;
00061   int packet_length = 0;
00062   int type = PACKET_UNKNOWN;
00063   int n;
00064 
00065   if (RecvTimeout < 0) {
00066     timeout = send_size << TIMEOUT_SHIFT;
00067   } else {
00068     timeout = RecvTimeout;
00069   }
00070 
00071 #ifdef __cplusplus
00072   if (!con) {
00073     throw RunCtrl_Exception("ConnectionDevice is not connected");
00074   }
00075 #else
00076   if (con < 0) {
00077     return -1;
00078   }
00079 #endif
00080 
00081   do {
00082     // リトライ
00083     if (state == SendRetry) {
00084       state = WaitStartByte;
00085       sendRetryPacket(con, send_packet, send_size);
00086 
00087       require_size = NODE_ACCESS_PACKET_HEADER_SIZE;
00088       recv_buffer[0] = 0x00;
00089       filled = removeInvalidPacketHeader((unsigned char*)recv_buffer, filled);
00090       ++retry_times;
00091 
00092       // リトライに失敗
00093       if (retry_times > RetryTimes) {
00094 #ifdef __cplusplus
00095         return ConnectionDevice::RetryFail;
00096 #else
00097         return -1;
00098 #endif
00099       }
00100     }
00101 
00102     // 受信処理
00103     filled = removeInvalidPacketHeader((unsigned char*)recv_buffer, filled);
00104 #ifdef __cplusplus
00105     n = con->recv(&recv_buffer[filled], require_size, timeout);
00106 #else
00107     n = device_recv(*con, &recv_buffer[filled], require_size, timeout);
00108 #endif
00109     if (n <= 0) {
00110       state = SendRetry;
00111       continue;
00112     }
00113     filled += n;
00114     require_size -= n;
00115     filled = removeInvalidPacketHeader((unsigned char*)recv_buffer, filled);
00116 
00117     if (state == WaitStartByte) {
00118       // スタートバイト待ち
00119       if ((filled >= 3) && (checkFirstTag((unsigned char*)recv_buffer) >= 0)) {
00120         state = WaitHeaderRecv;
00121       }
00122     }
00123     if (require_size > 0) {
00124       continue;
00125     }
00126     if (state == WaitHeaderRecv) {
00127       // ヘッダのチェックサム確認
00128       if (checkHeaderFormat((unsigned char*)recv_buffer) < 0) {
00129         state = SendRetry;
00130       } else {
00131         // ヘッダからパケット情報を取得
00132         long recv_unique_id = getPacketUniqueId((unsigned char*)recv_buffer);
00133         // ユニークID を確認
00134         if (recv_unique_id != unique_id) {
00135           state = SendRetry;
00136         }
00137         type = getPacketType((unsigned char*)recv_buffer);
00138         state = WaitPacketRecv;
00139         packet_length = getPacketLength((unsigned char*)recv_buffer);
00140         require_size += packet_length - NODE_ACCESS_PACKET_HEADER_SIZE;
00141       }
00142 
00143     } else if (state == WaitPacketRecv) {
00144       // パケットのチェックサムを確認
00145       if (checkPacketFormat((unsigned char*)recv_buffer, packet_length) < 0) {
00146         state = SendRetry;
00147       } else {
00148         state = RecvCompleted;
00149       }
00150     }
00151   } while (state != RecvCompleted);
00152 
00153   // 応答への処理
00154   if (type == PACKET_READ_RESPONSE) {
00155     // 読み出し応答への処理
00156     writeFromPacketData((unsigned char*)recv_buffer, (unsigned char *)tbl);
00157   }
00158   return 0;
00159 }
00160 

Generated on Mon Apr 13 22:52:04 2009 by  doxygen 1.5.7.1