00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00028 #include "dnxTransport.h"
00029 #include "dnxTSPI.h"
00030
00031 #include "dnxDebug.h"
00032 #include "dnxError.h"
00033 #include "dnxLogging.h"
00034 #include "dnxProtocol.h"
00035
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <unistd.h>
00039 #include <string.h>
00040 #include <pthread.h>
00041 #include <syslog.h>
00042 #include <errno.h>
00043 #include <assert.h>
00044 #include <sys/socket.h>
00045 #include <netinet/in.h>
00046 #include <arpa/inet.h>
00047
00048 #define elemcount(x) (sizeof(x)/sizeof(*(x)))
00049
00051 #define DNX_MAX_CHAN_MAP 1000
00052
00054 typedef struct DnxChanMap_
00055 {
00056 char * name;
00057 char * url;
00058 int (*txAlloc)(char * url, iDnxChannel ** icpp);
00059 } DnxChanMap;
00060
00062 typedef struct DnxTransport
00063 {
00064 char * scheme;
00065 char * libpath;
00066 int (*txAlloc)(char * url, iDnxChannel ** icpp);
00067 int (*txInit)(int (**ptxAlloc)(char * url, iDnxChannel ** icpp));
00068 void (*txExit)(void);
00069 } DnxTransport;
00070
00071
00072
00073
00074
00075
00076 #include "dnxTcp.h"
00077 #include "dnxUdp.h"
00078 #include "dnxMsgQ.h"
00079
00080 static DnxTransport gTMList[] =
00081 {
00082 { "tcp", 0, 0, dnxTcpInit, dnxTcpDeInit },
00083 { "udp", 0, 0, dnxUdpInit, dnxUdpDeInit },
00084 { "msgq", 0, 0, dnxMsgQInit, dnxMsgQDeInit },
00085 };
00086
00087
00088
00089 static int dnxInit = 0;
00090 static pthread_mutex_t chanMutex;
00091 static DnxChanMap gChannelMap[DNX_MAX_CHAN_MAP];
00092
00093
00094
00095
00096
00106 char * dnxNtop(const void * sastr, char * buf, size_t bufsz)
00107 {
00108 const struct sockaddr * sa = (const struct sockaddr *)sastr;
00109
00110 if (!sa)
00111 {
00112 strncpy(buf, "<Unknown Address>", bufsz);
00113 buf[bufsz - 1] = 0;
00114 return buf;
00115 }
00116 switch(sa->sa_family)
00117 {
00118 case AF_INET:
00119 inet_ntop(AF_INET, &((struct sockaddr_in *)sa)->sin_addr, buf, bufsz);
00120 break;
00121
00122 case AF_INET6:
00123 inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr),buf, INET6_ADDRSTRLEN);
00124 break;
00125
00126 default:
00127 strncpy(buf, "<Unknown AF>", bufsz);
00128 buf[bufsz - 1] = 0;
00129 break;
00130 }
00131 return buf;
00132 }
00133
00141 static int dnxChanMapUrlParse(DnxChanMap * chanMap, char * url)
00142 {
00143 char * ep;
00144 int i;
00145
00146 assert(chanMap && url && strlen(url) <= DNX_MAX_URL);
00147
00148
00149 if ((ep = strstr(url, "://")) == 0)
00150 return DNX_ERR_BADURL;
00151
00152
00153 for (i = 0; i < elemcount(gTMList); i++)
00154 if (!strncmp(url, gTMList[i].scheme, ep - url))
00155 {
00156 chanMap->txAlloc = gTMList[i].txAlloc;
00157 break;
00158 }
00159
00160 return i < elemcount(gTMList) ? DNX_OK : DNX_ERR_BADURL;
00161 }
00162
00163
00164
00172 static int dnxChanMapFindSlot(DnxChanMap ** chanMap)
00173 {
00174 int i;
00175
00176 assert(chanMap);
00177
00178
00179 for (i = 0; i < DNX_MAX_CHAN_MAP && gChannelMap[i].name; i++)
00180 ;
00181
00182 *chanMap = (DnxChanMap *)((i < DNX_MAX_CHAN_MAP) ? &gChannelMap[i] : 0);
00183
00184 return *chanMap ? DNX_OK : DNX_ERR_CAPACITY;
00185 }
00186
00187
00188
00197 static int dnxChanMapFindName(char * name, DnxChanMap ** chanMap)
00198 {
00199 int i;
00200
00201 assert(name && *name && chanMap);
00202
00203
00204 for (i = 0; i < DNX_MAX_CHAN_MAP; i++)
00205 if (gChannelMap[i].name && !strcmp(name, gChannelMap[i].name))
00206 break;
00207
00208 *chanMap = (DnxChanMap *)((i < DNX_MAX_CHAN_MAP) ? &gChannelMap[i] : 0);
00209
00210 return *chanMap ? DNX_OK : DNX_ERR_NOTFOUND;
00211 }
00212
00213
00214
00223 static int dnxChanMapAllocChannel(char * name, iDnxChannel ** icpp)
00224 {
00225 DnxChanMap * chanMap;
00226 int ret;
00227
00228 assert(name && *name && icpp);
00229
00230 DNX_PT_MUTEX_LOCK(&chanMutex);
00231
00232 if ((ret = dnxChanMapFindName(name, &chanMap)) == DNX_OK)
00233 ret = chanMap->txAlloc(chanMap->url, icpp);
00234
00235 DNX_PT_MUTEX_UNLOCK(&chanMutex);
00236
00237 return ret;
00238 }
00239
00240
00241
00242
00243
00251 int dnxChanMapAdd(char * name, char * url)
00252 {
00253 DnxChanMap tmp, * chanMap;
00254 int ret;
00255
00256 assert(name && *name && url && strlen(url) < DNX_MAX_URL);
00257
00258
00259 if ((ret = dnxChanMapUrlParse(&tmp, url)) != DNX_OK)
00260 return ret;
00261
00262
00263 if ((tmp.name = xstrdup(name)) == 0 || (tmp.url = xstrdup(url)) == 0)
00264 {
00265 xfree(tmp.name);
00266 return DNX_ERR_MEMORY;
00267 }
00268
00269 DNX_PT_MUTEX_LOCK(&chanMutex);
00270
00271
00272 if ((ret = dnxChanMapFindName(name, &chanMap)) == DNX_OK
00273 || (ret = dnxChanMapFindSlot(&chanMap)) == DNX_OK)
00274 {
00275 xfree(chanMap->name);
00276 xfree(chanMap->url);
00277 memcpy(chanMap, &tmp, sizeof *chanMap);
00278 }
00279
00280 DNX_PT_MUTEX_UNLOCK(&chanMutex);
00281
00282
00283 if (ret != DNX_OK)
00284 {
00285 xfree(tmp.name);
00286 xfree(tmp.url);
00287 }
00288 return ret;
00289 }
00290
00291
00292
00297 void dnxChanMapDelete(char * name)
00298 {
00299 DnxChanMap * chanMap;
00300
00301 assert(name && *name);
00302
00303 DNX_PT_MUTEX_LOCK(&chanMutex);
00304
00305
00306 if (dnxChanMapFindName(name, &chanMap) == DNX_OK)
00307 {
00308
00309 xfree(chanMap->name);
00310 xfree(chanMap->url);
00311 memset(chanMap, 0, sizeof *chanMap);
00312 }
00313
00314 DNX_PT_MUTEX_UNLOCK(&chanMutex);
00315 }
00316
00317
00318
00336 int dnxConnect(char * name, int mode, DnxChannel ** channel)
00337 {
00338 DnxChanMap * chanMap;
00339 iDnxChannel * icp;
00340 int ret;
00341
00342 assert(name && *name && channel);
00343
00344
00345 if ((ret = dnxChanMapAllocChannel(name, &icp)) == DNX_OK)
00346 {
00347 if ((ret = icp->txOpen(icp, mode)) != DNX_OK)
00348 icp->txDelete(icp);
00349 }
00350 if (ret == DNX_OK)
00351 *channel = (DnxChannel *)icp;
00352 return ret;
00353 }
00354
00355
00356
00361 void dnxDisconnect(DnxChannel * channel)
00362 {
00363 iDnxChannel * icp = (iDnxChannel *)channel;
00364
00365 assert(channel);
00366
00367 if (icp->txClose(icp) == DNX_OK)
00368 icp->txDelete(icp);
00369 }
00370
00371
00372
00389 int dnxGet(DnxChannel * channel, char * buf, int * size, int timeout, char * src)
00390 {
00391 iDnxChannel * icp = (iDnxChannel *)channel;
00392 assert(channel && buf && size && *size > 0);
00393 return icp->txRead(icp, buf, size, timeout, src);
00394 }
00395
00396
00397
00412 int dnxPut(DnxChannel * channel, char * buf, int size, int timeout, char * dst)
00413 {
00414 iDnxChannel * icp = (iDnxChannel *)channel;
00415 assert(channel && buf && size > 0 && size < DNX_MAX_MSG);
00416 return icp->txWrite(icp, buf, size, timeout, dst);
00417 }
00418
00419
00420
00426 void dnxGetStats(DnxChannel * channel, DnxTransStats * tsp)
00427 {
00428 iDnxChannel * icp = (iDnxChannel *)channel;
00429 assert(channel && tsp);
00430 if (icp->txGetStats)
00431 icp->txGetStats(icp, tsp);
00432 }
00433
00434
00435
00440 void dnxResetStats(DnxChannel * channel)
00441 {
00442 iDnxChannel * icp = (iDnxChannel *)channel;
00443 assert(channel);
00444 if (icp->txResetStats)
00445 icp->txResetStats(icp);
00446 }
00447
00448
00449
00457 int dnxChanMapInit(char * fileName)
00458 {
00459 int i;
00460
00461 assert(!dnxInit);
00462
00463 memset(gChannelMap, 0, sizeof gChannelMap);
00464
00465 DNX_PT_MUTEX_INIT(&chanMutex);
00466
00467
00468 for (i = 0; i < elemcount(gTMList); i++)
00469 {
00470 int ret;
00471 if ((ret = gTMList[i].txInit(&gTMList[i].txAlloc)) != DNX_OK)
00472 {
00473 while (i--) gTMList[i].txExit();
00474 DNX_PT_MUTEX_DESTROY(&chanMutex);
00475 return ret;
00476 }
00477 }
00478
00481 dnxInit = 1;
00482
00483 return DNX_OK;
00484 }
00485
00486
00487
00490 void dnxChanMapRelease(void)
00491 {
00492 if (dnxInit)
00493 {
00494 int i;
00495
00496 DNX_PT_MUTEX_LOCK(&chanMutex);
00497
00498 for (i = 0; i < DNX_MAX_CHAN_MAP; i++)
00499 {
00500 xfree(gChannelMap[i].name);
00501 xfree(gChannelMap[i].url);
00502 }
00503
00504 memset(gChannelMap, 0, sizeof gChannelMap);
00505
00506 DNX_PT_MUTEX_UNLOCK(&chanMutex);
00507 DNX_PT_MUTEX_DESTROY(&chanMutex);
00508
00509
00510 i = elemcount(gTMList);
00511 while (i--) gTMList[i].txExit();
00512
00513 dnxInit = 0;
00514 }
00515 }
00516
00517
00518