00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef hsms_msg_h
00021 #define hsms_msg_h
00022
00023 #include <arpa/inet.h>
00024 #include "log.h"
00025
00026 #define HSMS_CTRL_SESSION_ID 0xffff
00027 #define HSMS_LEN_BYTES_LEN 4
00028 #define HSMS_HDR_LEN 10
00029 #define HSMS_HDR_OFFSET HSMS_LEN_BYTES_LEN
00030 #define HSMS_SESSION_OFFSET HSMS_HDR_OFFSET
00031 #define HSMS_BYTE2_OFFSET 6
00032 #define HSMS_BYTE3_OFFSET 7
00033 #define HSMS_PTYPE_OFFSET 8
00034 #define HSMS_STYPE_OFFSET 9
00035 #define HSMS_SYSBYTES_OFFSET 10
00036 #define HSMS_DATABYTES_OFFSET 14
00037
00038 #define HSMS_MSG_STYPE(m) *((unsigned char*)((m)+HSMS_STYPE_OFFSET))
00039 #define HSMS_MSG_PTYPE(m) *((unsigned char*)((m)+HSMS_PTYPE_OFFSET))
00040 #define HSMS_MSG_LEN(m) *((unsigned*)(m))
00041 #define HSMS_MSG_BYTE2(m) *((unsigned char*)((m)+HSMS_BYTE2_OFFSET))
00042 #define HSMS_MSG_BYTE3(m) *((unsigned char*)((m)+HSMS_BYTE3_OFFSET))
00043 #define HSMS_SESSION_ID(m) *((unsigned short*)((m)+HSMS_SESSION_OFFSET))
00044 #define HSMS_CTRL_STATUS(m) *((unsigned short*)((m)+HSMS_BYTE2_OFFSET))
00045 #define HSMS_STREAM(m) *((unsigned char*)((m)+HSMS_BYTE2_OFFSET))
00046 #define HSMS_FUNCTION(m) *((unsigned char*)((m)+HSMS_BYTE3_OFFSET))
00047 #define HSMS_SYSBYTES(m) *((unsigned*)((m)+HSMS_SYSBYTES_OFFSET))
00048 #define HSMS_DATABYTES(m) ((unsigned char*)((m)+HSMS_DATABYTES_OFFSET))
00049
00050 #define HSMS_MSG_LOG_LEVEL 10
00051
00052 namespace freesecs
00053 {
00060 template < typename data_t >
00061 class hsms_msg_base
00062 {
00063 public:
00064 virtual ~hsms_msg_base(){};
00065 typedef enum _msg_et
00066 {
00067 e_data = 0,
00068 e_select_req = 1,
00069 e_select_rsp = 2,
00070 e_deselect_req = 3,
00071 e_deselect_rsp = 4,
00072 e_linktest_req = 5,
00073 e_linktest_rsp = 6,
00074 e_reject_req = 7,
00075 e_separate_req = 9,
00076 e_invalid = 0xff
00077 }
00078 msg_et;
00079
00080 virtual bool
00081 valid(const data_t &d) const
00082 {
00083 TRACE_DEBUG(HSMS_MSG_LOG_LEVEL,
00084 "msg_base::valid: msg_len: %d,"
00085 " msg.size: %d, type: %d",
00086 ntohl(HSMS_MSG_LEN(&d[0])), d.size(),
00087 HSMS_MSG_STYPE(&d[0]));
00088
00089 return HSMS_HDR_LEN <= ntohl(HSMS_MSG_LEN(&d[0]))
00090 && d.size() >= ntohl(HSMS_MSG_LEN(&d[0])) + HSMS_LEN_BYTES_LEN
00091 && e_separate_req >= HSMS_MSG_STYPE(&d[0]);
00092 };
00093
00094 msg_et
00095 type(const data_t &d)
00096 {
00097 return (msg_et)HSMS_MSG_STYPE(&d[0]);
00098 };
00099
00100 unsigned
00101 transaction_id(const data_t &d)
00102 {
00103 return ntohl(HSMS_SYSBYTES(&d[0]));
00104 };
00105 };
00106
00110 template < typename data_t >
00111 class select_req : public hsms_msg_base<data_t>
00112 {
00113 public:
00114 typedef hsms_msg_base<data_t> base_t;
00115
00116 static const unsigned short
00117 ctrl_session_id = 0xffff;
00118
00119 virtual bool
00120 valid(const data_t &d) const
00121 {
00122 return HSMS_HDR_LEN == ntohl(HSMS_MSG_LEN(&d[0]))
00123 && d.size() >= ntohl(HSMS_MSG_LEN(&d[0])) + HSMS_LEN_BYTES_LEN
00124 && base_t::e_select_req == HSMS_MSG_STYPE(&d[0])
00125 && 0 == HSMS_MSG_PTYPE(&d[0])
00126 && 0 == HSMS_CTRL_STATUS(&d[0])
00127 && HSMS_CTRL_SESSION_ID == HSMS_SESSION_ID(&d[0]);
00128 };
00129 void
00130 compose(data_t &d, unsigned transaction_id)
00131 {
00132 d = data_t(HSMS_LEN_BYTES_LEN + HSMS_HDR_LEN, 0);
00133 HSMS_MSG_LEN(&d[0]) = htonl(HSMS_HDR_LEN);
00134 HSMS_MSG_STYPE(&d[0]) = base_t::e_select_req;
00135 HSMS_SYSBYTES(&d[0]) = htonl(transaction_id);
00136 HSMS_SESSION_ID(&d[0]) = HSMS_CTRL_SESSION_ID;
00137 };
00138 };
00139
00143 template < typename data_t >
00144 class select_rsp : public hsms_msg_base<data_t>
00145 {
00146 public:
00147 typedef hsms_msg_base<data_t> base_t;
00148
00149 typedef enum _status_et
00150 {
00151 e_established = 0,
00152 e_already_active = 1,
00153 e_not_ready = 2,
00154 e_ctx_exhaust = 3,
00155 } status_et;
00156
00157 virtual bool
00158 valid(const data_t &d) const
00159 {
00160 return HSMS_HDR_LEN == ntohl(HSMS_MSG_LEN(&d[0]))
00161 && d.size() >= ntohl(HSMS_MSG_LEN(&d[0])) + HSMS_LEN_BYTES_LEN
00162 && base_t::e_select_rsp == HSMS_MSG_STYPE(&d[0])
00163 && 0 == HSMS_MSG_PTYPE(&d[0])
00164 && HSMS_CTRL_SESSION_ID == HSMS_SESSION_ID(&d[0]);
00165 };
00166 status_et
00167 status(const data_t &d) const
00168 {
00169 return (status_et) HSMS_MSG_BYTE3(&d[0]);
00170 };
00171 void
00172 compose(data_t &d, unsigned transaction_id, status_et status)
00173 {
00174 d = data_t(HSMS_LEN_BYTES_LEN + HSMS_HDR_LEN, 0);
00175 HSMS_MSG_LEN(&d[0]) = htonl(HSMS_HDR_LEN);
00176 HSMS_MSG_STYPE(&d[0]) = base_t::e_select_rsp;
00177 HSMS_CTRL_STATUS(&d[0]) = status;
00178 HSMS_SYSBYTES(&d[0]) = htonl(transaction_id);
00179 HSMS_SESSION_ID(&d[0]) = HSMS_CTRL_SESSION_ID;
00180 };
00181 };
00182
00186 template < typename data_t >
00187 class linktest_req : public hsms_msg_base<data_t>
00188 {
00189 public:
00190 typedef hsms_msg_base<data_t> base_t;
00191
00192 virtual bool
00193 valid(const data_t &d) const
00194 {
00195 return HSMS_HDR_LEN == ntohl(HSMS_MSG_LEN(&d[0]))
00196 && d.size() >= ntohl(HSMS_MSG_LEN(&d[0])) + HSMS_LEN_BYTES_LEN
00197 && base_t::e_linktest_req == HSMS_MSG_STYPE(&d[0])
00198 && 0 == HSMS_MSG_PTYPE(&d[0])
00199 && HSMS_CTRL_SESSION_ID == HSMS_SESSION_ID(&d[0]);
00200 };
00201 void
00202 compose(data_t &d, unsigned transaction_id)
00203 {
00204 d = data_t(HSMS_LEN_BYTES_LEN + HSMS_HDR_LEN, 0);
00205 HSMS_MSG_LEN(&d[0]) = htonl(HSMS_HDR_LEN);
00206 HSMS_MSG_STYPE(&d[0]) = base_t::e_linktest_req;
00207 HSMS_SYSBYTES(&d[0]) = htonl(transaction_id);
00208 HSMS_SESSION_ID(&d[0]) = HSMS_CTRL_SESSION_ID;
00209 };
00210 };
00211
00215 template < typename data_t >
00216 class linktest_rsp : public hsms_msg_base<data_t>
00217 {
00218 public:
00219 typedef hsms_msg_base<data_t> base_t;
00220
00221 virtual bool
00222 valid(const data_t &d) const
00223 {
00224 return HSMS_HDR_LEN == ntohl(HSMS_MSG_LEN(&d[0]))
00225 && d.size() >= ntohl(HSMS_MSG_LEN(&d[0])) + HSMS_LEN_BYTES_LEN
00226 && base_t::e_linktest_rsp == HSMS_MSG_STYPE(&d[0])
00227 && 0 == HSMS_MSG_PTYPE(&d[0])
00228 && HSMS_CTRL_SESSION_ID == HSMS_SESSION_ID(&d[0]);
00229 };
00230 void
00231 compose(data_t &d, unsigned transaction_id)
00232 {
00233 d = data_t(HSMS_LEN_BYTES_LEN + HSMS_HDR_LEN, 0);
00234 HSMS_MSG_LEN(&d[0]) = htonl(HSMS_HDR_LEN);
00235 HSMS_MSG_STYPE(&d[0]) = base_t::e_linktest_rsp;
00236 HSMS_SYSBYTES(&d[0]) = htonl(transaction_id);
00237 HSMS_SESSION_ID(&d[0]) = HSMS_CTRL_SESSION_ID;
00238 };
00239 };
00240
00244 template < typename data_t >
00245 class reject_req : public hsms_msg_base<data_t>
00246 {
00247 public:
00248 typedef hsms_msg_base<data_t> base_t;
00249
00250 typedef enum _reason_et
00251 {
00252 e_stype_not_supported = 1,
00253 e_ptype_not_supported = 2,
00254 e_transaction_not_open = 3,
00255 e_not_selected = 4
00256 } reason_et;
00257 virtual bool
00258 valid(const data_t &d)const
00259 {
00260 return HSMS_HDR_LEN == ntohl(HSMS_MSG_LEN(&d[0]))
00261 && d.size() >= ntohl(HSMS_MSG_LEN(&d[0])) + HSMS_LEN_BYTES_LEN
00262 && base_t::e_reject_req == HSMS_MSG_STYPE(&d[0]);
00263 };
00264 unsigned short
00265 session_id(data_t &d)
00266 {
00267 return ntohl(HSMS_SESSION_ID(&d[0]));
00268 };
00269 unsigned char
00270 byte2(data_t &d)
00271 {
00272 return HSMS_MSG_BYTE2(&d[0]);
00273 };
00274 reason_et
00275 reason(data_t &d)
00276 {
00277 return (reason_et) HSMS_MSG_BYTE3(&d[0]);
00278 };
00279 void
00280 compose(data_t &d, unsigned transaction_id,
00281 unsigned short session_id, unsigned char byte2, reason_et reason)
00282 {
00283 d = data_t(HSMS_LEN_BYTES_LEN + HSMS_HDR_LEN, 0);
00284 HSMS_MSG_LEN(&d[0]) = htonl(HSMS_HDR_LEN);
00285 HSMS_MSG_STYPE(&d[0]) = base_t::e_reject_req;
00286 HSMS_SYSBYTES(&d[0]) = htonl(transaction_id);
00287 HSMS_SESSION_ID(&d[0]) = htons(session_id);
00288 HSMS_MSG_BYTE2(&d[0]) = byte2;
00289 HSMS_MSG_BYTE3(&d[0]) = reason;
00290 };
00291 };
00292
00296 template < typename data_t >
00297 class separate_req : public hsms_msg_base<data_t>
00298 {
00299 public:
00300 typedef hsms_msg_base<data_t> base_t;
00301
00302 virtual bool
00303 valid(const data_t &d) const
00304 {
00305 return HSMS_HDR_LEN == htonl(HSMS_MSG_LEN(&d[0]))
00306 && d.size() >= htonl(HSMS_MSG_LEN(&d[0])) + HSMS_LEN_BYTES_LEN
00307 && base_t::e_separate_req == HSMS_MSG_STYPE(&d[0])
00308 && 0 == HSMS_MSG_BYTE2(&d[0])
00309 && 0 == HSMS_MSG_BYTE3(&d[0])
00310 && 0 == HSMS_MSG_PTYPE(&d[0])
00311 && HSMS_CTRL_SESSION_ID == HSMS_SESSION_ID(&d[0]);
00312 };
00313 void
00314 compose(data_t &d, unsigned transaction_id)
00315 {
00316 d = data_t(HSMS_LEN_BYTES_LEN + HSMS_HDR_LEN, 0);
00317 HSMS_MSG_LEN(&d[0]) = htonl(HSMS_HDR_LEN);
00318 HSMS_MSG_STYPE(&d[0]) = base_t::e_separate_req;
00319 HSMS_SYSBYTES(&d[0]) = htonl(transaction_id);
00320 HSMS_SESSION_ID(&d[0]) = HSMS_CTRL_SESSION_ID;
00321 };
00322 };
00323
00327 template < typename data_t >
00328 class data_msg : public hsms_msg_base<data_t>
00329 {
00330 public:
00331 typedef hsms_msg_base<data_t> base_t;
00332
00333 virtual bool
00334 valid(const data_t &d) const
00335 {
00336 return HSMS_HDR_LEN <= ntohl(HSMS_MSG_LEN(&d[0]))
00337 && d.size() >= ntohl(HSMS_MSG_LEN(&d[0])) + HSMS_LEN_BYTES_LEN
00338 && base_t::e_data == HSMS_MSG_STYPE(&d[0])
00339 && 0 == HSMS_MSG_PTYPE(&d[0]);
00340 };
00341 unsigned short
00342 session_id(const data_t &d)
00343 {
00344 return ntohl(HSMS_SESSION_ID(&d[0]));
00345 };
00346 unsigned char
00347 wbit(const data_t &d)
00348 {
00349 return HSMS_MSG_BYTE2(&d[0]) >> 7 & 0x1;
00350 };
00351 unsigned char
00352 stream(const data_t &d)
00353 {
00354 return HSMS_MSG_BYTE2(&d[0]) & 0x7F;
00355 };
00356 unsigned char
00357 function(const data_t &d)
00358 {
00359 return HSMS_MSG_BYTE3(&d[0]);
00360 };
00361 unsigned
00362 text_len(const data_t &d)
00363 {
00364 return ntohl(HSMS_MSG_LEN(&d[0])) - HSMS_HDR_LEN;
00365 }
00366 bool
00367 get_text(const data_t &d, data_t &text_data)
00368 {
00369 if (!valid(d))
00370 {
00371 return false;
00372 }
00373 text_data = data_t(&d[HSMS_DATABYTES_OFFSET], &d[HSMS_DATABYTES_OFFSET+text_len(d)]);
00374 return true;
00375 }
00376 void
00377 compose( data_t &d,
00378 unsigned char stream,
00379 unsigned char function,
00380 unsigned char wbit,
00381 unsigned int transaction_id,
00382 unsigned text_len,
00383 unsigned char *text)
00384 {
00385 d = data_t(HSMS_LEN_BYTES_LEN + HSMS_HDR_LEN + text_len, 0);
00386
00387 unsigned char *begin = &d[0];
00388 unsigned char *text_begin = begin + HSMS_DATABYTES_OFFSET;
00389
00390 HSMS_MSG_LEN(begin) = htonl(HSMS_HDR_LEN + text_len);
00391 HSMS_MSG_STYPE(begin) = base_t::e_data;
00392 HSMS_SYSBYTES(begin) = htonl(transaction_id);
00393
00394
00395 HSMS_MSG_BYTE2(begin) = stream & 0x7F;
00396 HSMS_MSG_BYTE3(begin) = function;
00397 HSMS_MSG_BYTE2(begin) |= (wbit & 0x1) << 7;
00398
00399 if(text)
00400 {
00401 memcpy(text_begin, text, text_len);
00402 }
00403 }
00404 void set_session_id(data_t &d, unsigned short session_id)
00405 {
00406 HSMS_SESSION_ID(&d[0]) = session_id & 0x7fff;
00407 }
00408 };
00409 }
00410 #endif //hsms_msg