Go to the documentation of this file.00001
00025 #include "stdint.h"
00026 #include <stdlib.h>
00027 #include <string.h>
00028
00029 #if defined(_USE_WIN_API)
00030 #include <winsock2.h>
00031 #pragma comment(lib, "wsock32.lib")
00032 #elif defined(_USE_LINUX_API)
00033 #include <arpa/inet.h>
00034 #include <errno.h>
00035 #include <sys/time.h>
00036 #ifndef strnicmp
00037 #define strnicmp strncasecmp
00038 #endif
00039 #else
00040 #include "dn_additional.h"
00041 #endif
00042
00043 #include "dn_common.h"
00044 #include "dn_device.h"
00045
00046 #define _STR_ISNUMERIC "0123456789"
00047
00048 #define _TYPE_MIN (3)
00049 #define _PARA_MAX_COM (7)
00050 #define _PARA_MAX_ETH (5)
00051
00052
00053 #ifndef __LITTLE_ENDIAN__
00054 #ifndef __BIG_ENDIAN__
00055 #if __BYTE_ORDER == __LITTLE_ENDIAN
00056 #define __LITTLE_ENDIAN__
00057 #elif __BYTE_ORDER == __BIG_ENDIAN
00058 #define __BIG_ENDIAN__
00059 #endif
00060 #endif
00061 #endif
00062
00068 static int
00069 is_numeric(const char *src)
00070 {
00071 int len;
00072
00073
00074 if ((src == NULL) || ((len = strlen(src)) == 0)) {
00075 return 0;
00076 }
00077
00078
00079 if (*src == '-') {
00080 src++;
00081 len--;
00082 }
00083
00084 return (strspn(src, _STR_ISNUMERIC) == len);
00085 }
00086
00092 int
00093 parse_conn_type(const char *opt)
00094 {
00095 int type = -1;
00096
00097 if (opt != NULL && strlen(opt) >= _TYPE_MIN) {
00098 if (strnicmp(opt, "tcp", _TYPE_MIN) == 0) {
00099 type = CONN_TCP;
00100 }
00101 else if (strnicmp(opt, "udp", _TYPE_MIN) == 0) {
00102 type = CONN_UDP;
00103 }
00104 else if (strnicmp(opt, "com", _TYPE_MIN) == 0) {
00105 type = CONN_COM;
00106 }
00107 }
00108
00109 return type;
00110 }
00111
00120 HRESULT
00121 parse_conn_param_ether(const char *opt, struct CONN_PARAM_ETH *param)
00122 {
00123 int tmp, type, n = 0;
00124 uint32_t uitmp;
00125 char *top, *pos, *pos_param[_PARA_MAX_ETH];
00126 char *opt_cpy = NULL;
00127 HRESULT hr = E_INVALIDARG;
00128
00129 if (param != NULL) {
00130 type = parse_conn_type(opt);
00131 if ((type == CONN_TCP) || (type == CONN_UDP)) {
00132
00133 opt_cpy = (char *) malloc(strlen(opt) + 1);
00134
00135 if (opt_cpy == NULL) {
00136 hr = E_OUTOFMEMORY;
00137 goto exit_proc;
00138 }
00139
00140 strcpy(opt_cpy, opt);
00141
00142
00143 top = opt_cpy;
00144 while (1) {
00145 if (n >= _PARA_MAX_ETH) {
00146 goto exit_proc;
00147 }
00148
00149 pos_param[n++] = top;
00150
00151 pos = strchr(top, ':');
00152 if (pos == NULL) {
00153 break;
00154 }
00155
00156 *pos = '\0';
00157 top = (pos + 1);
00158 }
00159
00160
00161 if (n >= 5) {
00162 if (is_numeric(pos_param[4]) == 0) {
00163 goto exit_proc;
00164 }
00165 tmp = atoi(pos_param[4]);
00166 if ((tmp < 0) || (tmp != (uint16_t) tmp)) {
00167 hr = DISP_E_OVERFLOW;
00168 goto exit_proc;
00169 }
00170 param->src_port = htons(tmp);
00171 }
00172
00173
00174 if (n >= 4) {
00175 uitmp = inet_addr(pos_param[3]);
00176 if (uitmp == htonl(INADDR_NONE)
00177 && strcmp(pos_param[3], "255.255.255.255") != 0)
00178 {
00179 goto exit_proc;
00180 }
00181 param->src_addr = uitmp;
00182 }
00183
00184
00185 if (n >= 3) {
00186 if (is_numeric(pos_param[2]) == 0) {
00187 goto exit_proc;
00188 }
00189 tmp = atoi(pos_param[2]);
00190 if ((tmp < 0) || (tmp != (uint16_t) tmp)) {
00191 hr = DISP_E_OVERFLOW;
00192 goto exit_proc;
00193 }
00194 param->dst_port = htons(tmp);
00195 }
00196
00197
00198 if (n >= 2) {
00199 uitmp = inet_addr(pos_param[1]);
00200 if (uitmp == htonl(INADDR_NONE)
00201 && strcmp(pos_param[1], "255.255.255.255") != 0)
00202 {
00203 goto exit_proc;
00204 }
00205 param->dst_addr = uitmp;
00206 }
00207
00208 hr = S_OK;
00209 }
00210 }
00211
00212 exit_proc:
00213 if (opt_cpy != NULL) {
00214 free(opt_cpy);
00215 opt_cpy = NULL;
00216 }
00217
00218 return hr;
00219 }
00220
00234 HRESULT
00235 parse_conn_param_serial(const char *opt, struct CONN_PARAM_COM *param)
00236 {
00237 int type, n = 0;
00238 long tmp;
00239 char *top, *pos, *pos_param[_PARA_MAX_COM];
00240 char *opt_cpy = NULL;
00241 HRESULT hr = E_INVALIDARG;
00242
00243 if (param != NULL) {
00244 type = parse_conn_type(opt);
00245 if (type == CONN_COM) {
00246
00247 opt_cpy = (char *) malloc(strlen(opt) + 1);
00248
00249 if (opt_cpy == NULL) {
00250 hr = E_OUTOFMEMORY;
00251 goto exit_proc;
00252 }
00253
00254 strcpy(opt_cpy, opt);
00255
00256
00257 top = opt_cpy;
00258 while (1) {
00259 if (n >= _PARA_MAX_COM) {
00260 goto exit_proc;
00261 }
00262
00263 pos_param[n++] = top;
00264
00265 pos = strchr(top, ':');
00266 if (pos == NULL) {
00267 break;
00268 }
00269
00270 *pos = '\0';
00271 top = (pos + 1);
00272 }
00273
00274 if (n == 4 || n == 5) {
00275 goto exit_proc;
00276 }
00277
00278
00279 if (n >= 7) {
00280 if (is_numeric(pos_param[6]) == 0) {
00281 goto exit_proc;
00282 }
00283 tmp = atol(pos_param[6]);
00284 if (tmp < 0 || 3 < tmp) {
00285 hr = DISP_E_OVERFLOW;
00286 goto exit_proc;
00287 }
00288 param->flow = (char) tmp;
00289 }
00290
00291
00292 if (n >= 6) {
00293 tmp = (int) (atof(pos_param[5]) * 10.0);
00294
00295 switch (tmp) {
00296 case 10:
00297 param->stop_bits = ONESTOPBIT;
00298 break;
00299 case 20:
00300 param->stop_bits = TWOSTOPBITS;
00301 break;
00302 default:
00303 goto exit_proc;
00304 }
00305 }
00306
00307
00308 if (n >= 5) {
00309 if (is_numeric(pos_param[4]) == 0) {
00310 goto exit_proc;
00311 }
00312 tmp = atol(pos_param[4]);
00313 if (tmp < 5 || 8 < tmp) {
00314 hr = DISP_E_OVERFLOW;
00315 goto exit_proc;
00316 }
00317 param->data_bits = (char) tmp;
00318 }
00319
00320
00321 if (n >= 4) {
00322 if (strlen(pos_param[3]) != 1) {
00323 goto exit_proc;
00324 }
00325
00326 switch (*pos_param[3]) {
00327 case L'N':
00328 case L'n':
00329 param->parity = NOPARITY;
00330 break;
00331 case L'O':
00332 case L'o':
00333 param->parity = ODDPARITY;
00334 break;
00335 case L'E':
00336 case L'e':
00337 param->parity = EVENPARITY;
00338 break;
00339 default:
00340 goto exit_proc;
00341 }
00342 }
00343
00344
00345 if (n >= 3) {
00346 if (is_numeric(pos_param[2]) == 0) {
00347 goto exit_proc;
00348 }
00349 param->baud_rate = (uint32_t) atol(pos_param[2]);
00350 }
00351
00352
00353 if (n >= 2) {
00354 if (is_numeric(pos_param[1]) == 0) {
00355 goto exit_proc;
00356 }
00357 tmp = atol(pos_param[1]);
00358 if ((tmp < 0) || (tmp != (int) tmp)) {
00359 hr = DISP_E_OVERFLOW;
00360 goto exit_proc;
00361 }
00362 param->port = tmp;
00363 }
00364
00365 hr = S_OK;
00366 }
00367 }
00368
00369 exit_proc:
00370 if (opt_cpy != NULL) {
00371 free(opt_cpy);
00372 opt_cpy = NULL;
00373 }
00374
00375 return hr;
00376 }
00377
00384 HRESULT
00385 check_timeout(int sock, uint32_t timeout)
00386 {
00387 int ret;
00388 fd_set fds;
00389 struct timeval tv;
00390 HRESULT hr = S_OK;
00391
00392 if (sock <= 0)
00393 return E_HANDLE;
00394
00395 FD_ZERO(&fds); FD_SET(sock, &fds);
00396
00397 tv.tv_sec = timeout / 1000;
00398 tv.tv_usec = (timeout % 1000) * 1000;
00399
00400 ret = select(sock + 1, &fds, NULL, NULL, &tv);
00401 if (ret == 0) {
00402 hr = E_TIMEOUT;
00403 }
00404 else if (ret < 0) {
00405 ret = DNGetLastError();
00406 hr = OSERR2HRESULT(ret);
00407 }
00408
00409 return hr;
00410 }
00411
00418 HRESULT
00419 check_conn_param(const struct CONN_PARAM_COMMON *device, int flag)
00420 {
00421 if (device == NULL)
00422 return E_INVALIDARG;
00423
00424
00425 if (device->sock <= 0)
00426 return E_HANDLE;
00427
00428
00429 if (flag & CHECK_TYPE_ALL) {
00430 if (!(flag & device->type))
00431 return E_INVALIDARG;
00432 }
00433
00434
00435 if ((flag & CHECK_FUNC_OPEN) && (device->dn_open == NULL))
00436 return E_INVALIDARG;
00437
00438
00439 if ((flag & CHECK_FUNC_CLOSE) && (device->dn_close == NULL))
00440 return E_INVALIDARG;
00441
00442
00443 if ((flag & CHECK_FUNC_SEND) && (device->dn_send == NULL))
00444 return E_INVALIDARG;
00445
00446
00447 if ((flag & CHECK_FUNC_RECV) && (device->dn_recv == NULL))
00448 return E_INVALIDARG;
00449
00450
00451 if ((flag & CHECK_FUNC_TIMEOUT) && (device->dn_set_timeout == NULL))
00452 return E_INVALIDARG;
00453
00454
00455 if ((flag & CHECK_FUNC_CLEAR) && (device->dn_clear == NULL))
00456 return E_INVALIDARG;
00457
00458 return S_OK;
00459 }
00460
00468 void
00469 memcpy_le(void *dst, const void *src, uint32_t len)
00470 {
00471 #ifdef __BIG_ENDIAN__
00472 uint32_t i;
00473 uint8_t *pdst;
00474 uint8_t *psrc;
00475
00476 psrc = (uint8_t *)(src) + len - 1;
00477 pdst = (uint8_t *)(dst);
00478
00479 for (i = 0; i < len; i++) {
00480 *pdst++ = *psrc--;
00481 }
00482 #else
00483 memcpy(dst, src, len);
00484 #endif
00485 }
00486
00494 void
00495 memcpy_be(void *dst, const void *src, uint32_t len)
00496 {
00497 #ifndef __BIG_ENDIAN__
00498 uint32_t i;
00499 uint8_t *pdst;
00500 uint8_t *psrc;
00501
00502 psrc = (uint8_t *) (src) + len - 1;
00503 pdst = (uint8_t *) (dst);
00504
00505 for (i = 0; i < len; i++) {
00506 *pdst++ = *psrc--;
00507 }
00508 #else
00509 memcpy(dst, src, len);
00510 #endif
00511 }