selfcare init
This commit is contained in:
32
proxy_c/Makefile
Normal file
32
proxy_c/Makefile
Normal file
@@ -0,0 +1,32 @@
|
||||
TOPDIR:=.
|
||||
TGT:=./restproxy
|
||||
|
||||
DIR=$(TOPDIR)
|
||||
SRCS=$(foreach dir, $(DIR), $(wildcard $(dir)/*.c))
|
||||
OBJS:=$(patsubst %.c,%.o,$(SRCS))
|
||||
|
||||
|
||||
|
||||
DIR_LIBEVENT = ./third-lib/libevent/include/
|
||||
DIR_JSON = ./third-lib/json-lib/inc/
|
||||
DIR_CURL = ./third-lib/libcurl/include/curl/
|
||||
|
||||
INCDIR = $(foreach dir, $(DIR), -I $(dir)/ )
|
||||
INCDIR += -I $(DIR_LIBEVENT)
|
||||
INCDIR += -I $(DIR_JSON)
|
||||
INCDIR += -I $(DIR_CURL)
|
||||
|
||||
LIBS = ./dba/lib/libdba.a ./smcli_client/lib/libclient.a ./pstn_cli/lib/libpstncli.a ./tcp/lib/libtcp.a /usr/lib/x86_64-linux-gnu/libidn.a -I/usr/include/mysql -L/usr/lib64/mysql -lmysqlclient ./third-lib/libcurl/lib/libcurl.a -lrt -lcrypto -lssl -lpthread ./third-lib/libevent/lib/libevent.a ./third-lib/libevent/lib/libevent_pthreads.a ./third-lib/json-lib/libmjson.a -L/usr/local/lib -lglib-2.0 -lz
|
||||
|
||||
CFLAGS = -Wall -g -DX86_64 -DTEST_RESTPROXY $(LIBS)
|
||||
|
||||
CC = gcc
|
||||
|
||||
$(TGT):$(OBJS)
|
||||
$(CC) -o $(TGT) $(CFLAGS) $(SRCS) $(INCDIR) $(LIBS)
|
||||
chmod a+x $(TGT)
|
||||
|
||||
$(OBJS):%.o:%.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $< $(INCDIR)
|
||||
clean:
|
||||
rm -rf $(OBJS) $(TGT)
|
||||
33
proxy_c/Makefile.bak
Normal file
33
proxy_c/Makefile.bak
Normal file
@@ -0,0 +1,33 @@
|
||||
TOPDIR:=.
|
||||
TGT:=./restproxy
|
||||
|
||||
DIR=$(TOPDIR)
|
||||
SRCS=$(foreach dir, $(DIR), $(wildcard $(dir)/*.c))
|
||||
OBJS:=$(patsubst %.c,%.o,$(SRCS))
|
||||
|
||||
|
||||
|
||||
DIR_LIBEVENT = ./third-lib/libevent/include/
|
||||
DIR_JSON = ./third-lib/json-lib/inc/
|
||||
DIR_CURL = ./third-lib/libcurl/include/curl/
|
||||
|
||||
INCDIR = $(foreach dir, $(DIR), -I $(dir)/ )
|
||||
INCDIR += -I $(DIR_LIBEVENT)
|
||||
INCDIR += -I $(DIR_JSON)
|
||||
INCDIR += -I $(DIR_CURL)
|
||||
|
||||
LIBS = /usr/lib/x86_64-linux-gnu/libidn.a ./third-lib/libcurl/lib/libcurl.a -lrt -lcrypto -lssl -lpthread ./third-lib/libevent/lib/libevent.a ./third-lib/json-lib/libmjson.a
|
||||
|
||||
|
||||
CFLAGS = -Wall -g -DX86_64 -DTEST_RESTPROXY $(LIBS)
|
||||
|
||||
CC = gcc
|
||||
|
||||
$(TGT):$(OBJS)
|
||||
$(CC) -o $(TGT) $(CFLAGS) $(SRCS) $(INCDIR) $(LIBS)
|
||||
chmod a+x $(TGT)
|
||||
|
||||
$(OBJS):%.o:%.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $< $(INCDIR)
|
||||
clean:
|
||||
rm -rf $(OBJS) $(TGT)
|
||||
BIN
proxy_c/Makefile_rules.tgz
Normal file
BIN
proxy_c/Makefile_rules.tgz
Normal file
Binary file not shown.
12
proxy_c/Readme.txt
Normal file
12
proxy_c/Readme.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
1)<29><>װlibmysqlclient
|
||||
apt-get install libmysqlclient-dev
|
||||
|
||||
2)make dba
|
||||
<EFBFBD><EFBFBD>װglib
|
||||
#cd dba;make
|
||||
|
||||
3)xlocale.h not found
|
||||
ln -s /usr/include/locale.h /usr/include/xlocale.h
|
||||
|
||||
4)undefined reference to idn2_free
|
||||
third-lib/curl-7.52.1#>./configure --without-libidn --without-libidn2
|
||||
181
proxy_c/common.c
Normal file
181
proxy_c/common.c
Normal file
@@ -0,0 +1,181 @@
|
||||
#include<time.h>
|
||||
#include "common.h"
|
||||
|
||||
extern char *strptime(const char *s, const char *format, struct tm *tm);
|
||||
void BcdToAscii (char *ascii_buf, const BYTE *bcd_buf, int len)
|
||||
{
|
||||
int i;
|
||||
char ch;
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
if (i & 1) ch = *(bcd_buf++) & 0x0f;
|
||||
else ch = *bcd_buf >> 4;
|
||||
ascii_buf[i] = ch + ((ch > 9)? 'A'-10 : '0');
|
||||
}
|
||||
ascii_buf[i] = '\0';
|
||||
}
|
||||
|
||||
void BcdToAsciiR(char *ascii_buf, const unsigned char *bcd_buf, int len)
|
||||
{
|
||||
char ch;
|
||||
int i;
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
sprintf(&ascii_buf[i*2],"%02X",bcd_buf[i]);
|
||||
ch = ascii_buf[i*2];
|
||||
ascii_buf[i*2] = ascii_buf[i*2+1];
|
||||
ascii_buf[i*2+1] = ch;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char *GetAsciiTime()
|
||||
{
|
||||
char *pAscTime;
|
||||
time_t tCurTime;
|
||||
|
||||
tCurTime = time(NULL);
|
||||
pAscTime = ctime(&tCurTime);
|
||||
|
||||
return (char *)pAscTime;
|
||||
}
|
||||
|
||||
int GetCurrentTime( char *pNowTime )
|
||||
{
|
||||
struct tm *pTMNowTime;
|
||||
time_t tTemptime;
|
||||
|
||||
tTemptime = time(NULL);
|
||||
pTMNowTime = localtime(&tTemptime);
|
||||
if( pTMNowTime == NULL )
|
||||
return 0;
|
||||
pNowTime[0] = pTMNowTime->tm_year-100;
|
||||
pNowTime[1] = pTMNowTime->tm_mon+1;
|
||||
pNowTime[2] = pTMNowTime->tm_mday;
|
||||
pNowTime[3] = pTMNowTime->tm_hour;
|
||||
pNowTime[4] = pTMNowTime->tm_min;
|
||||
pNowTime[5] = pTMNowTime->tm_sec;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int GetMonthDay()
|
||||
{
|
||||
struct tm *pTMNowTime;
|
||||
time_t tTemptime;
|
||||
|
||||
tTemptime = time(NULL);
|
||||
pTMNowTime = localtime(&tTemptime);
|
||||
if( pTMNowTime == NULL )
|
||||
return 1;
|
||||
return pTMNowTime->tm_mday;
|
||||
|
||||
}
|
||||
|
||||
ulong TransStrTimeToSecond(const char *str_time)//YYYY-MM-DD HH:MM:YY
|
||||
{
|
||||
struct tm nowTm;
|
||||
time_t longT;
|
||||
|
||||
if(str_time == NULL)
|
||||
return 0;
|
||||
|
||||
strptime(str_time,"%Y-%m-%d %H:%M:%S",&nowTm);
|
||||
longT = mktime(&nowTm);
|
||||
|
||||
return longT;
|
||||
}
|
||||
|
||||
int print_buf_in_fmt_ascii(char *ascii_buf, unsigned char *bcd_buf, int len)
|
||||
{
|
||||
int i;
|
||||
char tmp_buf[128];
|
||||
|
||||
memset(ascii_buf, 0x00, len*3);
|
||||
|
||||
for(i=0;i<len%300; i++)
|
||||
{
|
||||
sprintf(tmp_buf,"%02x ",bcd_buf[i]);
|
||||
strcat(ascii_buf, tmp_buf);
|
||||
if((i+1)%16 == 0)
|
||||
{
|
||||
strcat(ascii_buf, "\r\n");
|
||||
}
|
||||
else if((i+1) %8 == 0)
|
||||
{
|
||||
strcat(ascii_buf," ");
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void SetTermSignal(struct termios *ptermio, void (*handler)(int))
|
||||
{
|
||||
/*
|
||||
ioctl(0,TCGETA, ptermio);
|
||||
ptermio->c_cc[VINTR] = '\x03';
|
||||
ioctl(0,TCSETA, ptermio);
|
||||
*/
|
||||
|
||||
signal(SIGINT, handler);
|
||||
signal(SIGKILL,handler);
|
||||
signal(SIGSTOP,handler);
|
||||
signal(SIGTERM,handler);
|
||||
signal(SIGSEGV,handler);
|
||||
}
|
||||
|
||||
void Terminate(int sig)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void SetFSMTimer()
|
||||
{
|
||||
struct itimerval *ptv, tv;
|
||||
|
||||
ptv = (struct itimerval *) &tv;
|
||||
ptv->it_interval.tv_sec = 0;
|
||||
ptv->it_value.tv_sec = 0;
|
||||
ptv->it_interval.tv_usec = 10000;
|
||||
ptv->it_value.tv_usec = 10000;
|
||||
|
||||
setitimer(ITIMER_REAL, ptv, NULL);
|
||||
}
|
||||
|
||||
void sysDaemonInit()
|
||||
{
|
||||
int i;
|
||||
pid_t pid;
|
||||
|
||||
if ( (pid = fork()) < 0) /* parent terminates */
|
||||
printf("%s: %s: fork (%d)", __FILE__, __FUNCTION__, __LINE__);
|
||||
else if (pid != 0)
|
||||
exit(0); /* parent goes bye-bye */
|
||||
|
||||
setsid(); /* become session leader */
|
||||
|
||||
for (i = 0; i<3; i++)
|
||||
close(i);
|
||||
}
|
||||
|
||||
extern int sys_timer10ms;
|
||||
void sysTimer_IRQ()
|
||||
{
|
||||
sys_timer10ms = 1;
|
||||
}
|
||||
|
||||
void SigactionSystem()
|
||||
{
|
||||
struct sigaction action;//,actsegv;
|
||||
|
||||
action.sa_handler = sysTimer_IRQ;
|
||||
sigemptyset(&action.sa_mask);
|
||||
action.sa_flags = SA_RESTART;
|
||||
if(sigaction(SIGALRM, &action, NULL)<0)
|
||||
{
|
||||
printf("sigactin sigalarm failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
100
proxy_c/common.h
Normal file
100
proxy_c/common.h
Normal file
@@ -0,0 +1,100 @@
|
||||
#ifndef _COMMON_TYPE_H_
|
||||
#define _COMMON_TYPE_H_
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h> /* basic system data types */
|
||||
#include <sys/socket.h> /* basic socket definitions */
|
||||
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
|
||||
#include <arpa/inet.h> /* inet(3) functions */
|
||||
#include <netinet/sctp.h>
|
||||
#include <sys/epoll.h> /* epoll function */
|
||||
#include <fcntl.h> /* nonblocking */
|
||||
#include <sys/resource.h> /*setrlimit */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <termio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/io.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <pthread.h>
|
||||
#include <netinet/in.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/prctl.h>
|
||||
|
||||
|
||||
#ifndef u8
|
||||
typedef unsigned char u8;
|
||||
#endif
|
||||
|
||||
#ifndef u16
|
||||
typedef unsigned short int u16;
|
||||
#endif
|
||||
|
||||
#ifndef u32
|
||||
typedef unsigned int u32;
|
||||
#endif
|
||||
|
||||
#ifndef u64
|
||||
typedef unsigned long long u64;
|
||||
#endif
|
||||
|
||||
#ifndef BYTE
|
||||
typedef unsigned char BYTE;
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef SUCCESS
|
||||
#define SUCCESS (0)
|
||||
#endif
|
||||
|
||||
#ifndef FAILURE
|
||||
#define FAILURE (-1)
|
||||
#endif
|
||||
|
||||
#define MAX_BUFFER 1024
|
||||
|
||||
|
||||
/* common.c */
|
||||
extern void BcdToAscii (char *ascii_buf, const BYTE *bcd_buf, int len);
|
||||
|
||||
extern void BcdToAsciiR(char *ascii_buf, const unsigned char *bcd_buf, int len);
|
||||
|
||||
extern char *GetAsciiTime();
|
||||
|
||||
extern int GetCurrentTime( char *pNowTime );
|
||||
|
||||
extern int print_buf_in_fmt_ascii(char *ascii_buf, unsigned char *bcd_buf, int len);
|
||||
|
||||
extern void SetTermSignal(struct termios *ptermio, void (*handler)(int));
|
||||
|
||||
extern void Terminate(int sig);
|
||||
|
||||
extern void SetFSMTimer();
|
||||
|
||||
extern void sysDaemonInit();
|
||||
|
||||
extern void sysTimer_IRQ();
|
||||
|
||||
extern void SigactionSystem();
|
||||
|
||||
/* sock_if.c */
|
||||
extern int init_socket(unsigned int local_addr, short local_port, char stype, int noblock_flag);
|
||||
extern int udp_recv_with_ip_info(int fd, char *buf, short MAX_LEN, int *peer_ip, short *peer_port);
|
||||
extern int udp_send(int fd, int peer_ip, short peer_port, char *buf, short len);
|
||||
|
||||
/* mini_cli.c */
|
||||
extern int cli_read_cmd(char *buf);
|
||||
extern void debug_monitor(void *arg);
|
||||
|
||||
#endif
|
||||
33
proxy_c/conf/rest_proxy.conf
Normal file
33
proxy_c/conf/rest_proxy.conf
Normal file
@@ -0,0 +1,33 @@
|
||||
#rest proxy local ip and port as server
|
||||
localIPPort=192.168.139.131:4951
|
||||
|
||||
#restfull query ip&port
|
||||
queryIPPort=192.168.139.131:8080
|
||||
#restfull vourcher recharge ip&port
|
||||
rechargeIPPort=192.168.139.131:8080
|
||||
|
||||
#user/passwrd
|
||||
username=external
|
||||
password=password
|
||||
|
||||
subsystem=Selfcare
|
||||
customerIP=10.60.1.37
|
||||
#url_walletbalance=/rest-services/%s/xxx
|
||||
#url_rechargevoucher=/rest-services/%s/yyy
|
||||
|
||||
query_topup_getscriberid_switch=1
|
||||
url_walletbalance_getscriberid=/rest-services/subscriber/serviceinfo/MSISDN/%s/subscriberId
|
||||
url_walletbalance=/rest-services/subscriber/%s/allowances?identifierName=MSISDN&identifierValue=%s
|
||||
url_rechargevoucher_getscriberid=/rest-services/subscriber/serviceinfo/MSISDN/%s/subscriberId
|
||||
url_rechargevoucher=/rest-services/subscriber/%s/refillAccountByVoucher
|
||||
url_trans_getsubsid_sender=/rest-services/subscriber/serviceinfo/MSISDN/%s/subscriberId
|
||||
url_trans_getsubsid_receiver=/rest-services/subscriber/serviceinfo/MSISDN/%s/subscriberId
|
||||
#url_trans=/rest-services/subscriber/%s/giftCredit
|
||||
url_trans=/rest-services/generic/giftCredit
|
||||
|
||||
#test MSISDN
|
||||
test_msisdn=6924500002
|
||||
test_msisdn_in=6924500004
|
||||
#test_msisdn=77922417981167
|
||||
test_pin=63555825498329
|
||||
|
||||
33
proxy_c/conf/selfcare_proxy.conf
Normal file
33
proxy_c/conf/selfcare_proxy.conf
Normal file
@@ -0,0 +1,33 @@
|
||||
udp_localIPPort=192.168.1.229:4900
|
||||
udp_ocsIPPort=192.168.1.229:4951
|
||||
http_localPort=8080
|
||||
#authcode url
|
||||
authcode_url=/authcode
|
||||
#query_userdata url
|
||||
query_userdata_url=/query_userdata
|
||||
#bundle_subs url
|
||||
bundle_subs_url=/bundle_subs
|
||||
#bundle_usage url
|
||||
bundle_usage_url=/bundle_usage
|
||||
#recharge url
|
||||
recharge_url=/recharge
|
||||
#transfer url
|
||||
transfer_url=/transfer
|
||||
#recharge_card url
|
||||
recharge_card_url=/recharge_card
|
||||
#check_balance url
|
||||
check_balance_url=/check_balance
|
||||
#query_balane url
|
||||
query_balane_url=/query_balane
|
||||
#errcodes and their meanings
|
||||
errcode_map_message=[2001,success]
|
||||
errcode_map_message=[3001,command unsupported]
|
||||
errcode_map_message=[3010,unknown peer]
|
||||
errcode_map_message=[4001,invalid user status]
|
||||
errcode_map_message=[4008,dest user not allowed]
|
||||
errcode_map_message=[4012,credit limit]
|
||||
errcode_map_message=[5004,invalid parameter value]
|
||||
errcode_map_message=[5005,missing parameter]
|
||||
errcode_map_message=[5006,invalid recharge password]
|
||||
errcode_map_message=[5012,unable to comply]
|
||||
errcode_map_message=[5030,user unknown]
|
||||
638
proxy_c/curl_adaptor.c
Normal file
638
proxy_c/curl_adaptor.c
Normal file
@@ -0,0 +1,638 @@
|
||||
#include <pthread.h>
|
||||
#include <sys/prctl.h>
|
||||
#include "curl_adaptor.h"
|
||||
#include "utils_queue.h"
|
||||
// #include "json_adaptor.h"
|
||||
#include "rest_proxy.h"
|
||||
#include "log.h"
|
||||
|
||||
SRestFulInfo g_restful;
|
||||
|
||||
typedef struct _STablCurl
|
||||
{
|
||||
ECurlType curlType;
|
||||
char* curlFormat;
|
||||
}STablCurl;
|
||||
|
||||
/* curl table */
|
||||
STablCurl g_tab_url[] =
|
||||
{
|
||||
// {URL_FETCH_SUB, URLFetchSub},
|
||||
{URL_FETCH_UPBalance, URLFetchUPBalance},
|
||||
{URL_FETCH_InfoBalance, URLFetchInfoBalance},
|
||||
{URL_FETCH_WalletBalance_Getsubsid, URLFetchWalletBalanceGetsubsid},
|
||||
{URL_FETCH_WalletBalance, URLFetchWalletBalance},
|
||||
{URL_RECHAGRGE_Getsubsid, URLRechargeGetsubsid},
|
||||
{URL_RECHAGRGE, URLRecharge},
|
||||
{URL_TRANS_GetsubsidSender, URLTransGetsubidSender},
|
||||
{URL_TRANS_GetsubsidReceiver, URLTransGetsubidReceiver},
|
||||
{URL_TRANS, URLTrans},
|
||||
};
|
||||
|
||||
/* curl cache */
|
||||
static const int CURL_MAX_CONN = 200;
|
||||
static const int CURL_WAIT_TIME_US = 30*1000;
|
||||
static const int CURL_CB_TIME_OUT_MS = 500;
|
||||
|
||||
static CURL_ADAPTOR_APP_CB g_curl_adaptor_app_cb;
|
||||
|
||||
static queueADT g_curl_queue;
|
||||
static int g_curl_thread_running;
|
||||
|
||||
char *get_val_by_name(const char *str, const char *name, char dst_buf[], const int len)
|
||||
{
|
||||
char *p = strstr(str, name);
|
||||
if(p)
|
||||
{
|
||||
char val[2][64] = {{0}};
|
||||
sscanf(p, "%64[^:]: \"%64[^\"]", val[0], val[1]);
|
||||
snprintf(dst_buf, len, "%s", val[1]);
|
||||
LOG_D("[curl][recv] [%s]=>[%s],[%s]\n", str, val[0], val[1]);
|
||||
|
||||
return dst_buf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int curl_adaptor_resolve_cb_walletbalance(const char *str, unsigned int *balance)
|
||||
{
|
||||
char *p_1 = NULL;
|
||||
char *p_2 = NULL;
|
||||
char *p_3 = NULL;
|
||||
if( (p_1 = strstr(str, "balance") ) != NULL &&
|
||||
(p_2 = strstr(p_1, ":") ) != NULL &&
|
||||
(p_3 = strstr(p_2, "\"") ) != NULL)
|
||||
{
|
||||
char *p_4 = p_3 + 1;
|
||||
char *p = p_4;
|
||||
while(*p_4 != '"')
|
||||
{
|
||||
p_4++;
|
||||
}
|
||||
*p_4 = '\0';
|
||||
|
||||
*balance = atof(p) * 100;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int curl_adaptor_resolve_cb_validitydate_mon(const char* str, int *mon)
|
||||
{
|
||||
static char *str_mon[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||
int mon_num = sizeof(str_mon)/sizeof(str_mon[0]);
|
||||
int i = 0;
|
||||
for( ; i < mon_num; ++i)
|
||||
{
|
||||
if(strcmp(str, str_mon[i]) == 0)
|
||||
{
|
||||
*mon = i;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int curl_adaptor_resolve_cb_validitydate(const char *str, unsigned int *validitydate)
|
||||
{
|
||||
char data[48] = {0};
|
||||
if(get_val_by_name(str, "validitydate", data, sizeof(data)) == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
char str_dd[8] = {0};
|
||||
char str_mon[8] = {0};
|
||||
char str_year[8]= {0};
|
||||
char str_h[8] = {0};
|
||||
char str_m[8] = {0};
|
||||
char str_s[8] = {0};
|
||||
|
||||
int ret = sscanf(data, "%7[^-]-%7[^-]-%7[^ ] %7[^:]:%7[^:]:%7s",
|
||||
str_dd, str_mon, str_year, str_h, str_m, str_s);
|
||||
if(ret == 6 || ret == 3)
|
||||
{
|
||||
struct tm tm;
|
||||
time_t time;
|
||||
tm.tm_year = atoi(str_year) - 1900;
|
||||
curl_adaptor_resolve_cb_validitydate_mon(str_mon, &tm.tm_mon);
|
||||
tm.tm_mday = atoi(str_dd);
|
||||
tm.tm_hour = atoi(str_h);
|
||||
tm.tm_min = atoi(str_m);
|
||||
tm.tm_sec = atoi(str_s);
|
||||
|
||||
time = mktime(&tm);
|
||||
*validitydate = time;
|
||||
|
||||
LOG_D("[curl][recv] [%s-%s-%s %s:%s:%s]=>[%u]\n", str_year, str_mon, str_dd, str_h, str_m, str_s, *validitydate);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* function: handle receive http response and resovle the raw data
|
||||
*/
|
||||
static size_t curl_adaptor_resolve_cb(char *d, size_t n, size_t l, void *p)
|
||||
{
|
||||
char *p_find, *p_start;
|
||||
SCurlAdaptor *curAdaptor = (SCurlAdaptor*)p;
|
||||
|
||||
switch(curAdaptor->urlType)
|
||||
{
|
||||
case URL_FETCH_UPBalance:
|
||||
break;
|
||||
case URL_FETCH_InfoBalance:
|
||||
p_find = strstr(d, ":");
|
||||
if(p_find == NULL)
|
||||
{
|
||||
curAdaptor->msg.query_res.result = FAILURE;
|
||||
curAdaptor->msg.query_res.error_code = 0;
|
||||
curAdaptor->msg.query_res.optional_flag = 0;
|
||||
break;
|
||||
}
|
||||
p_find = p_start = strstr(p_find, "\"");
|
||||
p_find++;
|
||||
while((*p_find) != '\"')
|
||||
{
|
||||
p_find++;
|
||||
}
|
||||
*p_find = '\0';
|
||||
curAdaptor->msg.query_res.balance = (unsigned int)(atoi(p_start+1));
|
||||
curAdaptor->msg.query_res.result = SUCCESS;
|
||||
curAdaptor->msg.query_res.error_code = 0;
|
||||
curAdaptor->msg.query_res.optional_flag = 0;
|
||||
break;
|
||||
case URL_FETCH_WalletBalance_Getsubsid:
|
||||
get_val_by_name(d, "subscriberId", curAdaptor->msg.query.subsid, RESTFUL_SUBSID_LEN);
|
||||
break;
|
||||
case URL_FETCH_WalletBalance:
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if(d != NULL)
|
||||
{
|
||||
char *tmp = (char*)malloc(strlen(d) + 1);
|
||||
// char tmp[512] = {0};
|
||||
strcpy(tmp, d);
|
||||
|
||||
ret = curl_adaptor_resolve_cb_walletbalance(tmp, &curAdaptor->msg.query_res.balance);
|
||||
if(ret != 0)
|
||||
{
|
||||
strcpy(tmp, d);
|
||||
ret = curl_adaptor_resolve_cb_validitydate(tmp, &curAdaptor->msg.query_res.mo_expiry);
|
||||
}
|
||||
free(tmp);
|
||||
}
|
||||
if(ret != 0)
|
||||
{
|
||||
curAdaptor->msg.query_res.result = SUCCESS;
|
||||
curAdaptor->msg.query_res.mt_expiry = curAdaptor->msg.query_res.mo_expiry;
|
||||
}
|
||||
else
|
||||
{
|
||||
curAdaptor->msg.query_res.result = FAILURE;
|
||||
}
|
||||
|
||||
curAdaptor->msg.query_res.error_code = 0;
|
||||
curAdaptor->msg.query_res.optional_flag = 0;
|
||||
}
|
||||
break;
|
||||
case URL_RECHAGRGE_Getsubsid:
|
||||
get_val_by_name(d, "subscriberId", curAdaptor->msg.topup.subsid, RESTFUL_SUBSID_LEN);
|
||||
break;
|
||||
case URL_RECHAGRGE:
|
||||
{
|
||||
curAdaptor->msg.topup_res.result = SUCCESS;
|
||||
curAdaptor->msg.topup_res.error_code = 0;
|
||||
curAdaptor->msg.topup_res.balance = 0;
|
||||
curAdaptor->msg.topup_res.mo_expiry = 0;
|
||||
curAdaptor->msg.topup_res.mt_expiry = 0;
|
||||
curAdaptor->msg.topup_res.optional_flag = 0;
|
||||
}
|
||||
break;
|
||||
case URL_TRANS_GetsubsidSender:
|
||||
get_val_by_name(d, "subscriberId", curAdaptor->msg.transfer.subsid_sender, RESTFUL_SUBSID_LEN);
|
||||
break;
|
||||
case URL_TRANS_GetsubsidReceiver:
|
||||
get_val_by_name(d, "subscriberId", curAdaptor->msg.transfer.subsid_receiver, RESTFUL_SUBSID_LEN);
|
||||
break;
|
||||
case URL_TRANS:
|
||||
{
|
||||
curAdaptor->msg.transfer_res.result = SUCCESS;
|
||||
curAdaptor->msg.transfer_res.error_code = 0;
|
||||
curAdaptor->msg.transfer_res.optional_flag = 0;
|
||||
}
|
||||
break;
|
||||
case URL_PPC_OfferGetAllV2_1:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return n*l;
|
||||
}
|
||||
|
||||
static void curl_adaptor_easy_init(CURLM *cm, const SCurlAdaptor* curAdaptor)
|
||||
{
|
||||
CURL *eh = curl_easy_init();
|
||||
char userNamePasswordBuf[64] = {0};
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD>query<72><79>get-subscriberid<69><64>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>http-request<73><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD> */
|
||||
if(curAdaptor->urlType == URL_FETCH_WalletBalance ||
|
||||
curAdaptor->urlType == URL_FETCH_WalletBalance_Getsubsid ||
|
||||
curAdaptor->urlType == URL_RECHAGRGE_Getsubsid ||
|
||||
curAdaptor->urlType == URL_TRANS_GetsubsidSender ||
|
||||
curAdaptor->urlType == URL_TRANS_GetsubsidReceiver)
|
||||
{
|
||||
curl_easy_setopt(eh, CURLOPT_WRITEDATA, (void *)(curAdaptor));
|
||||
curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, curl_adaptor_resolve_cb);
|
||||
// curl_easy_setopt(eh, CURLOPT_HEADER, 0L);
|
||||
curl_easy_setopt(eh, CURLOPT_NOSIGNAL, 1);
|
||||
curl_easy_setopt(eh, CURLOPT_URL, curAdaptor->urlBuf);
|
||||
// <20><><EFBFBD><EFBFBD>basic <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ṩ<EFBFBD><E1B9A9>֤<EFBFBD><D6A4>Ϣ
|
||||
curl_easy_setopt(eh, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
snprintf(userNamePasswordBuf, sizeof(userNamePasswordBuf), "%s:%s",
|
||||
g_rest_proxy_env.cnf.username, g_rest_proxy_env.cnf.password);
|
||||
curl_easy_setopt(eh, CURLOPT_USERPWD, userNamePasswordBuf);
|
||||
curl_easy_setopt(eh, CURLOPT_PRIVATE, curAdaptor);
|
||||
// curl_easy_setopt(eh, CURLOPT_VERBOSE, 0L);
|
||||
curl_easy_setopt(eh, CURLOPT_TIMEOUT_MS, CURL_CB_TIME_OUT_MS);
|
||||
|
||||
curl_easy_setopt(eh, CURLOPT_FORBID_REUSE, 1);
|
||||
|
||||
LOG_D(" urlType:%d, curl:%s\n", curAdaptor->urlType, curAdaptor->urlBuf);
|
||||
}
|
||||
else if(curAdaptor->urlType == URL_RECHAGRGE ||
|
||||
curAdaptor->urlType == URL_TRANS)
|
||||
{
|
||||
/* <20><><EFBFBD><EFBFBD>topup<75><70>˵<EFBFBD><CBB5>topup<75><70>Ҫ<EFBFBD><D2AA>http-post<73><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.*/
|
||||
/* ע<><D7A2>: <20><><EFBFBD><EFBFBD>param<61><6D>ȫ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳̿<DFB3><CCBF>ܳ<EFBFBD><DCB3><EFBFBD>. <20><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD>°<EFBFBD>ȫ<EFBFBD><C8AB>. 2019/06/23 22:58:30 */
|
||||
static char param[512] = {0};
|
||||
|
||||
// <20><><EFBFBD><EFBFBD><EFBFBD>ʷ<EFBFBD>0<EFBFBD><30>ʾ<EFBFBD><CABE><EFBFBD>β<EFBFBD><CEB2><EFBFBD>Ϊpost
|
||||
curl_easy_setopt(eh, CURLOPT_POST, 1);
|
||||
// url<72><6C>ַ
|
||||
curl_easy_setopt(eh, CURLOPT_URL,curAdaptor->urlBuf);
|
||||
// <20><><EFBFBD><EFBFBD>basic <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ṩ<EFBFBD><E1B9A9>֤<EFBFBD><D6A4>Ϣ
|
||||
curl_easy_setopt(eh, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
|
||||
|
||||
snprintf(userNamePasswordBuf, sizeof(userNamePasswordBuf), "%s:%s",
|
||||
g_rest_proxy_env.cnf.username, g_rest_proxy_env.cnf.password);
|
||||
curl_easy_setopt(eh, CURLOPT_USERPWD, userNamePasswordBuf);
|
||||
|
||||
if(curAdaptor->urlType == URL_RECHAGRGE)
|
||||
{
|
||||
if(REST_PROXY_SUBSCRIBID_FLAG)
|
||||
{
|
||||
/* <20><><EFBFBD><EFBFBD>Ϊquery/topup<75><70><EFBFBD>̶<EFBFBD>Ҫ<EFBFBD>Ȼ<EFBFBD>ȡsubscriber-id<69>Ļ<EFBFBD><C4BB><EFBFBD> topup<75>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: */
|
||||
/* msisdn=90909093&&pin=39977093792343 */
|
||||
snprintf(param, sizeof(param), "msisdn=%s&pin=%s",
|
||||
curAdaptor->msg.topup.msisdn, curAdaptor->msg.topup.pin);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* <20><><EFBFBD><EFBFBD>Ϊquery/topup<75><70><EFBFBD>̲<EFBFBD><CCB2><EFBFBD><EFBFBD>Ȼ<EFBFBD>ȡsubscriber-id<69><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1>query/topup<75><70>self-http, topup<75>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: */
|
||||
/* char *post_para = "actor=4559936&pin=57160898969922&customerIp=10.60.1.42&voucherId=&subscriberId=4559936&subsystem=Selfcare&rechargeTransactiontId=1503&msisdn=6924559936" */
|
||||
snprintf(param, sizeof(param), "actor=%s&pin=%s&customerIp=%s&voucherId=%s&subscriberId=%s&subsystem=%s&msisdn=%s",
|
||||
curAdaptor->msg.topup.msisdn,
|
||||
curAdaptor->msg.topup.pin,
|
||||
g_rest_proxy_env.cnf.customer_ip,
|
||||
"",
|
||||
curAdaptor->msg.topup.msisdn,
|
||||
g_rest_proxy_env.cnf.subsystem,
|
||||
curAdaptor->msg.topup.msisdn);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(param, sizeof(param), "gifteeSubscriptionIdentifier=%s&&gifterSubscriptionIdentifier=%s&&BankTypeToCredit=WalletBank;;%u&&Comments=Gift WalletBank of $%u from %s to %s",
|
||||
curAdaptor->msg.transfer.msisdn_receiver,
|
||||
curAdaptor->msg.transfer.msisdn_sender,
|
||||
curAdaptor->msg.transfer.money,
|
||||
curAdaptor->msg.transfer.money,
|
||||
curAdaptor->msg.transfer.msisdn_sender,
|
||||
curAdaptor->msg.transfer.msisdn_receiver);
|
||||
}
|
||||
|
||||
|
||||
// post<73><74><EFBFBD><EFBFBD>
|
||||
curl_easy_setopt(eh, CURLOPT_POSTFIELDS, param);
|
||||
curl_easy_setopt(eh, CURLOPT_POSTFIELDSIZE, strlen(param) );
|
||||
// <20>Է<EFBFBD><D4B7>ص<EFBFBD><D8B5><EFBFBD><EFBFBD>ݽ<EFBFBD><DDBD>в<EFBFBD><D0B2><EFBFBD><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD><EFBFBD><EFBFBD>ַ
|
||||
curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, curl_adaptor_resolve_cb);
|
||||
// <20><><EFBFBD><EFBFBD>write_data<74>ĵ<EFBFBD><C4B5>ĸ<EFBFBD><C4B8><EFBFBD><EFBFBD><EFBFBD>ֵ
|
||||
curl_easy_setopt(eh, CURLOPT_WRITEDATA, curAdaptor);
|
||||
curl_easy_setopt(eh, CURLOPT_PRIVATE, curAdaptor);
|
||||
|
||||
{
|
||||
struct curl_slist *chunk = NULL;
|
||||
/* Remove a header curl would otherwise add by itself */
|
||||
chunk = curl_slist_append(chunk, "Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2");
|
||||
/* set our custom set of headers */
|
||||
curl_easy_setopt(eh, CURLOPT_HTTPHEADER, chunk);
|
||||
}
|
||||
// <20><>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
|
||||
// curl_easy_setopt(eh, CURLOPT_VERBOSE, 1);
|
||||
// <20><><EFBFBD><EFBFBD>Ӧͷ<D3A6><CDB7>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>һ<EFBFBD><EFBFBD>write_data
|
||||
curl_easy_setopt(eh, CURLOPT_HEADER, 1);
|
||||
// <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>0,<2C><>Ӧͷ<D3A6><CDB7>Ϣlocation
|
||||
// curl_easy_setopt(eh, CURLOPT_FOLLOWLOCATION, 1);
|
||||
|
||||
curl_easy_setopt(eh, CURLOPT_FORBID_REUSE, 1);
|
||||
|
||||
LOG_D(" urlType:%d, curl:%s param:%s\n", curAdaptor->urlType, curAdaptor->urlBuf, param);
|
||||
}
|
||||
|
||||
curl_multi_add_handle(cm, eh);
|
||||
|
||||
}
|
||||
|
||||
int curl_adaptor_init_cb(CURL_ADAPTOR_APP_CB appCB)
|
||||
{
|
||||
g_curl_adaptor_app_cb = appCB;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static int curl_adaptor_init_restfulInfo(const char* queryIP, unsigned int queryPort, const char* rechargeIP, unsigned int rechargePort)
|
||||
{
|
||||
strcpy(g_restful.queryIP, queryIP);
|
||||
g_restful.queryPort = queryPort;
|
||||
|
||||
strcpy(g_restful.recharegeIP, rechargeIP);
|
||||
g_restful.recharegePort = rechargePort;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int curl_adaptor_add(SCurlAdaptor* curAdaptor)
|
||||
{
|
||||
int len = 0;
|
||||
int rc = FAILURE;
|
||||
|
||||
if(QueueIsFull(g_curl_queue))
|
||||
{
|
||||
rc = FAILURE;
|
||||
goto END;
|
||||
}
|
||||
|
||||
int urlType = curAdaptor->urlType;
|
||||
switch(urlType)
|
||||
{
|
||||
case URL_FETCH_UPBalance:
|
||||
case URL_FETCH_InfoBalance:
|
||||
case URL_FETCH_WalletBalance_Getsubsid:
|
||||
{
|
||||
len = snprintf(curAdaptor->urlBuf, RESTFUL_CUL_BUF_MAX, "%s%s:%d",
|
||||
URLPrefix, g_restful.queryIP, g_restful.queryPort);
|
||||
len += snprintf(curAdaptor->urlBuf + len, RESTFUL_CUL_BUF_MAX - len,
|
||||
g_tab_url[urlType].curlFormat, curAdaptor->msg.query.msisdn);
|
||||
}
|
||||
break;
|
||||
case URL_FETCH_WalletBalance:
|
||||
{
|
||||
len = snprintf(curAdaptor->urlBuf, RESTFUL_CUL_BUF_MAX, "%s%s:%d",
|
||||
URLPrefix, g_restful.queryIP, g_restful.queryPort);
|
||||
if(REST_PROXY_SUBSCRIBID_FLAG)
|
||||
{
|
||||
/* <20><><EFBFBD><EFBFBD>Ϊquery/topup<75><70><EFBFBD>̶<EFBFBD>Ҫ<EFBFBD>Ȼ<EFBFBD>ȡsubscriber-id. query/topup<75><70>ʱ<EFBFBD><CAB1>Ҫ<EFBFBD><D2AA>subscriber-id<69>ͳ<EFBFBD>ȥ */
|
||||
len += snprintf(curAdaptor->urlBuf + len, RESTFUL_CUL_BUF_MAX - len,
|
||||
g_tab_url[urlType].curlFormat, curAdaptor->msg.query.subsid, curAdaptor->msg.query.msisdn);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* <20><><EFBFBD><EFBFBD>Ϊquery/topup<75><70><EFBFBD>̲<EFBFBD><CCB2><EFBFBD><EFBFBD>Ȼ<EFBFBD>ȡsubscriber-id<69><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>subscriber-id<69>ͳ<EFBFBD>ȥ */
|
||||
len += snprintf(curAdaptor->urlBuf + len, RESTFUL_CUL_BUF_MAX - len,
|
||||
g_tab_url[urlType].curlFormat, curAdaptor->msg.query.msisdn);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case URL_RECHAGRGE_Getsubsid:
|
||||
{
|
||||
len = snprintf(curAdaptor->urlBuf, RESTFUL_CUL_BUF_MAX, "%s%s:%d",
|
||||
URLPrefix, g_restful.recharegeIP, g_restful.recharegePort);
|
||||
len += snprintf(curAdaptor->urlBuf + len, RESTFUL_CUL_BUF_MAX - len,
|
||||
g_tab_url[urlType].curlFormat, curAdaptor->msg.topup.msisdn);
|
||||
}
|
||||
break;
|
||||
case URL_RECHAGRGE:
|
||||
{
|
||||
len = snprintf(curAdaptor->urlBuf, RESTFUL_CUL_BUF_MAX, "%s%s:%d",
|
||||
URLPrefix, g_restful.recharegeIP, g_restful.recharegePort);
|
||||
if(REST_PROXY_SUBSCRIBID_FLAG)
|
||||
{
|
||||
/* <20><><EFBFBD><EFBFBD>Ϊquery/topup<75><70><EFBFBD>̶<EFBFBD>Ҫ<EFBFBD>Ȼ<EFBFBD>ȡsubscriber-id. query/topup<75><70>ʱ<EFBFBD><CAB1>Ҫ<EFBFBD><D2AA>subscriber-id<69>ͳ<EFBFBD>ȥ */
|
||||
len += snprintf(curAdaptor->urlBuf + len, RESTFUL_CUL_BUF_MAX - len,
|
||||
g_tab_url[urlType].curlFormat, curAdaptor->msg.topup.subsid);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* <20><><EFBFBD><EFBFBD>Ϊquery/topup<75><70><EFBFBD>̲<EFBFBD><CCB2><EFBFBD><EFBFBD>Ȼ<EFBFBD>ȡsubscriber-id<69><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>subscriber-id<69>ͳ<EFBFBD>ȥ */
|
||||
len += snprintf(curAdaptor->urlBuf + len, RESTFUL_CUL_BUF_MAX - len,
|
||||
g_tab_url[urlType].curlFormat, curAdaptor->msg.topup.msisdn);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case URL_TRANS_GetsubsidSender:
|
||||
{
|
||||
len = snprintf(curAdaptor->urlBuf, RESTFUL_CUL_BUF_MAX, "%s%s:%d",
|
||||
URLPrefix, g_restful.recharegeIP, g_restful.recharegePort);
|
||||
len += snprintf(curAdaptor->urlBuf + len, RESTFUL_CUL_BUF_MAX - len,
|
||||
g_tab_url[urlType].curlFormat, curAdaptor->msg.transfer.msisdn_sender);
|
||||
|
||||
}
|
||||
break;
|
||||
case URL_TRANS_GetsubsidReceiver:
|
||||
{
|
||||
len = snprintf(curAdaptor->urlBuf, RESTFUL_CUL_BUF_MAX, "%s%s:%d",
|
||||
URLPrefix, g_restful.recharegeIP, g_restful.recharegePort);
|
||||
len += snprintf(curAdaptor->urlBuf + len, RESTFUL_CUL_BUF_MAX - len,
|
||||
g_tab_url[urlType].curlFormat, curAdaptor->msg.transfer.msisdn_receiver);
|
||||
|
||||
}
|
||||
break;
|
||||
case URL_TRANS:
|
||||
{
|
||||
len = snprintf(curAdaptor->urlBuf, RESTFUL_CUL_BUF_MAX, "%s%s:%d",
|
||||
URLPrefix, g_restful.recharegeIP, g_restful.recharegePort);
|
||||
len += snprintf(curAdaptor->urlBuf + len, RESTFUL_CUL_BUF_MAX - len, "%s",
|
||||
g_tab_url[urlType].curlFormat/*, curAdaptor->msg.transfer.subsid_sender*/);
|
||||
}
|
||||
break;
|
||||
case URL_PPC_OfferGetAllV2_1:
|
||||
{
|
||||
len = snprintf(curAdaptor->urlBuf, RESTFUL_CUL_BUF_MAX, "%s%s:%d",
|
||||
URLPrefix, g_restful.queryIP, g_restful.queryPort);
|
||||
len += snprintf(curAdaptor->urlBuf + len, RESTFUL_CUL_BUF_MAX - len,
|
||||
g_tab_url[urlType%URL_MAX_NUM].curlFormat, "-weekly,daily");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
rc = FAILURE;
|
||||
goto END;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(SUCCESS_QUEUE == QueueEnter(g_curl_queue, (queueElementT)curAdaptor) )
|
||||
{
|
||||
rc = SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = FAILURE;
|
||||
}
|
||||
|
||||
END:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* curl_multi_perform() + curl_multi_wait() */
|
||||
int curl_adaptor_go(SCurlAdaptor *curlAdaptor)
|
||||
{
|
||||
CURLM *cm = NULL;
|
||||
CURL *eh = NULL;
|
||||
CURLMsg *msg = NULL;
|
||||
CURLcode return_code = 0;
|
||||
int still_running = 0, msgs_left = 0;
|
||||
int http_status_code;
|
||||
|
||||
cm = curl_multi_init();
|
||||
if(cm == NULL) return FAILURE;
|
||||
/* we can optionally limit the total amount of connections this multi handle uses */
|
||||
curl_multi_setopt(cm, CURLMOPT_MAXCONNECTS, (long)CURL_MAX_CONN);
|
||||
curl_adaptor_easy_init(cm, curlAdaptor);
|
||||
curl_multi_perform(cm, &still_running);
|
||||
|
||||
do
|
||||
{
|
||||
int numfds=0;
|
||||
int res = curl_multi_wait(cm, NULL, 0, CURL_WAIT_TIME_US, &numfds);
|
||||
if(res != CURLM_OK)
|
||||
{
|
||||
LOG_E("[curl][recv] error: curl_multi_wait() returned %d\n", res);
|
||||
return FAILURE;
|
||||
}
|
||||
curl_multi_perform(cm, &still_running);
|
||||
|
||||
}while(still_running);
|
||||
|
||||
while((msg = curl_multi_info_read(cm, &msgs_left)))
|
||||
{
|
||||
if (msg->msg == CURLMSG_DONE)
|
||||
{
|
||||
curlAdaptor = NULL;
|
||||
|
||||
eh = msg->easy_handle;
|
||||
return_code = msg->data.result;
|
||||
curl_easy_getinfo(eh, CURLINFO_PRIVATE, &curlAdaptor);
|
||||
if(return_code != CURLE_OK)
|
||||
{
|
||||
LOG_E("[curl][recv] error: curl_multi_info_read() returned %d\n", return_code);
|
||||
|
||||
g_curl_adaptor_app_cb(curlAdaptor, msg->data.result);
|
||||
|
||||
curl_multi_remove_handle(cm, eh);
|
||||
curl_easy_cleanup(eh);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get HTTP status code */
|
||||
http_status_code = 0;
|
||||
curl_easy_getinfo(eh, CURLINFO_RESPONSE_CODE, &http_status_code);
|
||||
if(http_status_code != 200)
|
||||
{
|
||||
LOG_E("[curl][recv] get of %p returned http status code %d\n", curlAdaptor, http_status_code);
|
||||
}
|
||||
|
||||
g_curl_adaptor_app_cb(curlAdaptor, http_status_code);
|
||||
|
||||
curl_multi_remove_handle(cm, eh);
|
||||
curl_easy_cleanup(eh);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("[curl][recv] error: after curl_multi_info_read(), CURLMsg=%d\n", msg->msg);
|
||||
}
|
||||
}
|
||||
|
||||
curl_multi_cleanup(cm);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int curl_adaptor_init_queue()
|
||||
{
|
||||
g_curl_queue = QueueCreate(3000);
|
||||
|
||||
return g_curl_queue != NULL;
|
||||
}
|
||||
|
||||
static void *curl_adaptor_thread(void *data)
|
||||
{
|
||||
prctl(PR_SET_NAME, "curl_queue");
|
||||
|
||||
SCurlAdaptor *curAdaptor;
|
||||
|
||||
while(g_curl_thread_running)
|
||||
{
|
||||
if( !QueueIsEmpty(g_curl_queue) )
|
||||
{
|
||||
curAdaptor = (SCurlAdaptor *)QueueDelete(g_curl_queue);
|
||||
if(curAdaptor)
|
||||
{
|
||||
curl_adaptor_go(curAdaptor);
|
||||
}
|
||||
}
|
||||
usleep(10);
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int curl_adaptor_init_thread()
|
||||
{
|
||||
pthread_t handle;
|
||||
g_curl_thread_running = 1;
|
||||
if(pthread_create(&handle, NULL, curl_adaptor_thread, NULL))
|
||||
{
|
||||
printf("Thread create err !!!\n");
|
||||
return FAILURE;
|
||||
|
||||
if ( pthread_detach(handle) )
|
||||
{
|
||||
printf("Thread detached err !!!\n");
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int curl_adaptor_init(CURL_ADAPTOR_APP_CB appCB,
|
||||
const char* queryIP,
|
||||
unsigned int queryPort,
|
||||
const char* rechargeIP,
|
||||
unsigned int rechargePort)
|
||||
{
|
||||
curl_adaptor_init_queue();
|
||||
curl_adaptor_init_thread();
|
||||
curl_adaptor_init_cb(appCB);
|
||||
curl_adaptor_init_restfulInfo(queryIP, queryPort, rechargeIP, rechargePort);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int curl_adaptor_fini()
|
||||
{
|
||||
g_curl_thread_running = 0;
|
||||
|
||||
QueueDestroy(g_curl_queue);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
206
proxy_c/curl_adaptor.h
Normal file
206
proxy_c/curl_adaptor.h
Normal file
@@ -0,0 +1,206 @@
|
||||
#ifndef __CURL_ADAPTOR_H__
|
||||
#define __CURL_ADAPTOR_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include "multi.h"
|
||||
#include "curl.h"
|
||||
#include "easy.h"
|
||||
#include "common.h"
|
||||
|
||||
/* for For querying monetary or wallet balance */
|
||||
#define URLPrefix "" // "http://"
|
||||
#define URLFetchSub "/rest-services/subscriber/%s"
|
||||
#define URLFetchUPBalance "/rest-services/subscriber/%s/info/userpaymentbalance"
|
||||
#define URLFetchInfoBalance "/rest-services/subscriber/%s/info/balance"
|
||||
|
||||
/* url: <20><>ѯ */
|
||||
#define URLFetchWalletBalanceGetsubsid g_rest_proxy_env.cnf.url_fetchwalletbalance_getsubsid
|
||||
#define URLFetchWalletBalance g_rest_proxy_env.cnf.url_fetchwalletbalance
|
||||
|
||||
/* url: <20><>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>ֵ */
|
||||
#define URLRechargeGetsubsid g_rest_proxy_env.cnf.url_recharge_getsubsid
|
||||
#define URLRecharge g_rest_proxy_env.cnf.url_recharge
|
||||
|
||||
/* url: <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA> */
|
||||
#define URLTransGetsubidSender g_rest_proxy_env.cnf.url_trans_getsubsid_sender
|
||||
#define URLTransGetsubidReceiver g_rest_proxy_env.cnf.url_trans_getsubsid_receiver
|
||||
#define URLTrans g_rest_proxy_env.cnf.url_trans
|
||||
|
||||
#define RESTFUL_IP_SIZE 32
|
||||
#define RESTFUL_CUL_BUF_MAX 256
|
||||
|
||||
#define RESTFUL_SUBSID_LEN 24
|
||||
#define RESTFUL_MSISDN_LEN 24
|
||||
#define RESTFUL_USERNAME 64
|
||||
#define RESTFUL_PASSWOR 64
|
||||
|
||||
typedef struct _SRestfulInfo
|
||||
{
|
||||
char queryIP[RESTFUL_IP_SIZE];
|
||||
unsigned int queryPort;
|
||||
|
||||
char recharegeIP[RESTFUL_IP_SIZE];
|
||||
unsigned int recharegePort;
|
||||
}SRestFulInfo;
|
||||
|
||||
extern SRestFulInfo g_restful;
|
||||
|
||||
|
||||
typedef struct _SubscriberIdentity
|
||||
{
|
||||
unsigned char identityChoice; /*1:imsi,2:msisdn*/
|
||||
unsigned char msisdn[8+1]; /* TBCD */
|
||||
unsigned char imsi[8+1]; /* TBCD */
|
||||
|
||||
}SubscriberIdentity;
|
||||
|
||||
|
||||
typedef enum _ECurlType
|
||||
{
|
||||
// URL_FETCH_SUB = 0x00,
|
||||
|
||||
URL_FETCH_UPBalance = 0x00,
|
||||
URL_FETCH_InfoBalance,
|
||||
URL_FETCH_WalletBalance_Getsubsid,
|
||||
URL_FETCH_WalletBalance, /* for For querying monetary or wallet balance */
|
||||
URL_RECHAGRGE_Getsubsid,
|
||||
URL_RECHAGRGE, /* for Voucher recharge */
|
||||
|
||||
URL_TRANS_GetsubsidSender, /* ת<>˻<EFBFBD>ȡsender<65><72>subscriberID<49><44>url */
|
||||
URL_TRANS_GetsubsidReceiver, /* ת<>˻<EFBFBD>ȡreceiver<65><72>subscriberID<49><44>url */
|
||||
URL_TRANS, /* ת<>˵<EFBFBD>url */
|
||||
|
||||
URL_PPC_OfferGetAllV2_1,
|
||||
|
||||
URL_MAX_NUM,
|
||||
}ECurlType;
|
||||
|
||||
|
||||
|
||||
typedef struct _SCurlRestAdaptorHeader
|
||||
{
|
||||
unsigned short ppsAppID;
|
||||
unsigned short restproxyAppID;
|
||||
}SCurlRestAdaptorHeader;
|
||||
|
||||
typedef struct _SCurlDataFetchSubscribe
|
||||
{
|
||||
SubscriberIdentity subID;
|
||||
}SCurlDataFetchSubscribe;
|
||||
|
||||
typedef union _UCurlAdaptorVal
|
||||
{
|
||||
SCurlDataFetchSubscribe subscribeID;
|
||||
}UCurlAdaptorVal;
|
||||
|
||||
/* restful query struct */
|
||||
typedef struct _SCurlRestAdaptorQuery
|
||||
{
|
||||
char msisdn[RESTFUL_MSISDN_LEN];
|
||||
char subsid[RESTFUL_SUBSID_LEN];
|
||||
}SCurlRestAdaptorQuery;
|
||||
|
||||
/* restful query response struct */
|
||||
typedef struct _SCurlRestAdatptorQueryRes
|
||||
{
|
||||
char optional_flag;
|
||||
char result;
|
||||
char error_code;
|
||||
unsigned int balance;
|
||||
unsigned int mo_expiry;
|
||||
unsigned int mt_expiry;
|
||||
}SCurlRestAdatptorQueryRes;
|
||||
|
||||
/* restful topup struct */
|
||||
typedef struct _SCurlRestAdatptorTopup
|
||||
{
|
||||
char msisdn[RESTFUL_MSISDN_LEN];
|
||||
char pin[RESTFUL_MSISDN_LEN];
|
||||
|
||||
char subsid[RESTFUL_SUBSID_LEN];
|
||||
}SCurlRestAdatptorTopup;
|
||||
|
||||
/* restful topup response struct */
|
||||
typedef struct _SCurlRestAdatptorTopupRes
|
||||
{
|
||||
char optional_flag;
|
||||
char result;
|
||||
char error_code;
|
||||
unsigned int balance;
|
||||
unsigned int mo_expiry;
|
||||
unsigned int mt_expiry;
|
||||
}SCurlRestAdatptorTopupRes;
|
||||
|
||||
typedef struct _SCurlRestAdatptorTransfer
|
||||
{
|
||||
char msisdn_sender[24]; // ת<><D7AA><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD>
|
||||
char msisdn_receiver[24]; // ת<><D7AA><EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD>
|
||||
unsigned int money; // ת<>˽<EFBFBD><CBBD><EFBFBD>
|
||||
|
||||
char subsid_sender[RESTFUL_SUBSID_LEN]; // ת<><D7AA><EFBFBD>˺Ŷ<CBBA>Ӧ<EFBFBD><D3A6>subscriber-id
|
||||
char subsid_receiver[RESTFUL_SUBSID_LEN]; // ת<><D7AA><EFBFBD>˺Ŷ<CBBA>Ӧ<EFBFBD><D3A6>subscriber-id
|
||||
}SCurlRestAdatptorTransfer;
|
||||
|
||||
typedef struct _SCurlRestAdatptorTransferRes
|
||||
{
|
||||
unsigned char optional_flag;
|
||||
unsigned char result;
|
||||
unsigned char error_code;
|
||||
}SCurlRestAdatptorTransferRes;
|
||||
|
||||
typedef struct _SCurlAdaptor
|
||||
{
|
||||
ECurlType urlType;
|
||||
char urlBuf[RESTFUL_CUL_BUF_MAX];
|
||||
|
||||
SCurlRestAdaptorHeader header;
|
||||
union
|
||||
{
|
||||
SCurlRestAdaptorQuery query;
|
||||
SCurlRestAdatptorQueryRes query_res;
|
||||
SCurlRestAdatptorTopup topup;
|
||||
SCurlRestAdatptorTopupRes topup_res;
|
||||
SCurlRestAdatptorTransfer transfer;
|
||||
SCurlRestAdatptorTransferRes transfer_res;
|
||||
}msg;
|
||||
}SCurlAdaptor;
|
||||
|
||||
|
||||
/*
|
||||
* curl adaptor deliver the http request, receive and resolve the reponse, then pass the info to up layer
|
||||
* curAdaptor: resolve information
|
||||
* retCode: 200->success
|
||||
*/
|
||||
typedef int (*CURL_ADAPTOR_APP_CB)(SCurlAdaptor *curAdaptor, int retCode);
|
||||
|
||||
|
||||
/*
|
||||
* function: init curl adaptor.
|
||||
* appCB: curl upper layer call back
|
||||
* restfulIP: restful host ip. host order
|
||||
* restfulPort: restful port. host order
|
||||
* ret: SUCCESS or FAILURE
|
||||
*/
|
||||
int curl_adaptor_init(CURL_ADAPTOR_APP_CB appCB, const char* queryIP, unsigned int queryPort, const char* recharegeIP, unsigned int recharegePort);
|
||||
|
||||
/*
|
||||
* function: prepare to call restful api
|
||||
* curAdaptor: para that to be send as parameter
|
||||
* ret: SUCCESS or FAILURE
|
||||
*/
|
||||
int curl_adaptor_add(SCurlAdaptor* curAdaptor);
|
||||
|
||||
/*
|
||||
* function: relese curl adaptor resource
|
||||
* ret: SUCCESS or FAILURE
|
||||
*/
|
||||
int curl_adaptor_fini();
|
||||
|
||||
|
||||
#endif /* __CURL_ADAPTOR_H__ */
|
||||
53
proxy_c/dba/Makefile
Normal file
53
proxy_c/dba/Makefile
Normal file
@@ -0,0 +1,53 @@
|
||||
|
||||
MODULE = dba
|
||||
TYPE = plat
|
||||
|
||||
DBUG_FLAGS_ADD =
|
||||
RELS_FLAGS_ADD =
|
||||
|
||||
##Default commonly as below
|
||||
|
||||
BUILD = lib
|
||||
CFG = debug
|
||||
|
||||
|
||||
PLT_LIB = -DDEBUG
|
||||
|
||||
APP_LIB =
|
||||
LIB_ADD =
|
||||
|
||||
SRC_PATH = ./src
|
||||
INC_PATH = ./src/include
|
||||
PLT_PATH = ../../plat
|
||||
APP_PATH = ../../mss
|
||||
|
||||
OBJ_ADD =
|
||||
TEST_OBJ_PATH =
|
||||
|
||||
PREPROC_CMD =
|
||||
POSTPROC_CMD =
|
||||
|
||||
##---------------------------------------------------------------------##
|
||||
##--------------------------------------
|
||||
##
|
||||
## Make configuration(Customer define)
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
## CCFLAG_SWITCH = on/off => gcc flag show on/off
|
||||
## COVER_NEED = yes/no => PTF cover report needed
|
||||
## COVER_REPORT_PATH = [path ] => PTF cover report path
|
||||
|
||||
CCFLAG_SWITCH = off
|
||||
COVER_NEED = no
|
||||
COVER_REPORT_PATH = ./output
|
||||
|
||||
##---------------------------------------------------------------------##
|
||||
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## include makefile.rules (Do not change)
|
||||
##
|
||||
##--------------------------------------
|
||||
include ./scripts/Makefile.rules
|
||||
345
proxy_c/dba/scripts/Makefile.rules
Normal file
345
proxy_c/dba/scripts/Makefile.rules
Normal file
@@ -0,0 +1,345 @@
|
||||
|
||||
##----------------------------------------------------------##
|
||||
## ##
|
||||
## Universal Makefile Rules ##
|
||||
## ##
|
||||
## Created : Wei Liu 07/03/07 ##
|
||||
## Revision: [Last]Wei Liu 07/07/07 ##
|
||||
## ##
|
||||
##----------------------------------------------------------##
|
||||
|
||||
|
||||
UMAKE_VERSION := V2.0
|
||||
|
||||
##-------------------------------------
|
||||
##
|
||||
## Work Directory : /usr/local/include
|
||||
## Default Target : all
|
||||
##
|
||||
##-------------------------------------
|
||||
default: all
|
||||
.PHONY: all clean rebuild test indent splint doc \
|
||||
dir config check bk lsbk rmbk unzip umakever usage\
|
||||
FORCE
|
||||
.SUFFIXES:
|
||||
|
||||
umakever:
|
||||
@echo "Universal Makefile (UMake) Version: $(UMAKE_VERSION)"
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Makefile CFG defination check
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
ifeq "$(MODULE)" ""
|
||||
$(error Please input the module name (MODULE = )in makefile. )
|
||||
endif
|
||||
|
||||
ifeq "$(CFG)" ""
|
||||
CFG=debug
|
||||
$(warnning No configuration specified for CFG. Defaulting to $(MODULE) - debug. )
|
||||
endif
|
||||
|
||||
ifeq "$(BUILD)" ""
|
||||
BUILD=lib
|
||||
$(warnning No configuration specified for BUILD. Defaulting to create lib$(MODULE).a. )
|
||||
endif
|
||||
|
||||
ifeq "$(SRC_PATH)" ""
|
||||
SRC_PATH=.
|
||||
$(warnning No configuration specified for SRC_PATH. Defaulting to ./. )
|
||||
endif
|
||||
|
||||
COVER_NEED ?= no
|
||||
PLT_PATH ?= ../../plat
|
||||
APP_PATH ?= ../../app
|
||||
TYPE ?= plat
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Gcc Flag for debug or release
|
||||
##
|
||||
##--------------------------------------
|
||||
CC := gcc
|
||||
GCC_CFLAGS := -Wall -MM
|
||||
AR_LINK := ar -r
|
||||
|
||||
RELS_FLAGS_ADD += -DNDEBUG
|
||||
RELEASE_CFLAGS += -g -Wall -I. $(RELS_FLAGS_ADD) -I/usr/include/mysql -L/usr/lib64/mysql -lmysqlclient
|
||||
RELEASE_LINK_CFLAGS = -g $(RELS_FLAGS_ADD) -o
|
||||
DEBUG_CFLAGS += -g -Wall -rdynamic -DDEBUG -I. $(DBUG_FLAGS_ADD) -I/usr/include/mysql -L/usr/lib64/mysql -lmysqlclient -I/usr/include/openssl
|
||||
DEBUG_LINK_CFLAGS = -g -rdynamic -DDEBUG -o
|
||||
|
||||
GLIB_CFLAGS = -I/usr/include/glib-2.0
|
||||
GLIB_CFLAGS1 = -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
|
||||
|
||||
ifeq "$(COVER_NEED)" "yes"
|
||||
DEBUG_CFLAGS += -fprofile-arcs -ftest-coverage -pg
|
||||
endif
|
||||
|
||||
GCC_CFLAGS=$(DEBUG_CFLAGS) $(GLIB_CFLAGS) $(GLIB_CFLAGS1)
|
||||
GCC_LINK_CFLAGS=$(DEBUG_LINK_CFLAGS)
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Project setting
|
||||
##
|
||||
##--------------------------------------
|
||||
OBJDIR:=./obj
|
||||
LIBDIR:=./lib
|
||||
UTDIR :=./ut
|
||||
DOCDIR:=./doc
|
||||
DIRBUILD=$(OBJDIR)
|
||||
|
||||
ifeq "$(BUILD)" "lib"
|
||||
BINDIR:=./bin
|
||||
OUTFILE=$(LIBDIR)/lib$(MODULE).a
|
||||
DIRNEED=$(UTDIR) $(DOCDIR)
|
||||
DIRBUILD+=$(LIBDIR)
|
||||
else
|
||||
BINDIR:=.
|
||||
OUTFILE=$(BINDIR)/$(MODULE)
|
||||
DIRNEED=
|
||||
DIRBUILD+=$(BINDIR)
|
||||
endif
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## source , object and dependencies files
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
SRC_SUBDIR := $(shell find $(SRC_PATH) -type d)
|
||||
|
||||
vpath %.c $(SRC_SUBDIR)
|
||||
vpath %.o $(OBJDIR)
|
||||
vpath %.d $(OBJDIR)
|
||||
|
||||
SRC_FULL_PATH = $(foreach dir,$(SRC_SUBDIR),$(wildcard $(dir)/*.c))
|
||||
SRC_FILES = $(foreach file, $(notdir $(SRC_FULL_PATH)) ,$(OBJDIR)/$(file))
|
||||
COMMON_OBJ = $(SRC_FILES:%.c=%.o)
|
||||
|
||||
TEST_OBJ_PATH ?= ../../obj
|
||||
|
||||
TEST_OBJ = $(foreach dir,$(TEST_OBJ_PATH),$(wildcard $(dir)/*.o))
|
||||
|
||||
OBJ=$(COMMON_OBJ) $(OBJ_ADD)
|
||||
ALL_OBJ := $(OBJ) $(TEST_OBJ)
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Lib setting
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
ifeq "$(COVER_NEED)" "yes"
|
||||
LIBCOVER=-lgcov
|
||||
endif
|
||||
|
||||
MODULE_PLT_LIB=$(foreach lib,$(PLT_LIB), -L$(PLT_PATH)/$(lib)/lib/ -l$(lib) )
|
||||
MODULE_PLT_LIB+=-lm
|
||||
|
||||
|
||||
MODULE_APP_LIB=$(foreach lib,$(APP_LIB),-L$(APP_PATH)/$(lib)/lib -l$(lib))
|
||||
|
||||
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Rules
|
||||
##
|
||||
##--------------------------------------
|
||||
CCFLAG_SWITCH ?= off
|
||||
CC_COMPILE =$(CC) $(GCC_CFLAGS) -c $< -o $@
|
||||
CC_PRG_LINK=$(CC) $(GCC_LINK_CFLAGS) $(OUTFILE) $(ALL_OBJ) $(LIBCOVER) $(MODULE_APP_LIB) $(MODULE_PLT_LIB) $(LIB_ADD)
|
||||
CC_LIB_LINK=$(AR_LINK) $(OUTFILE) $(ALL_OBJ)
|
||||
|
||||
COMPILE=$(CC_COMPILE)
|
||||
PRG_LINK=$(CC_PRG_LINK)
|
||||
LIB_LINK=$(CC_LIB_LINK)
|
||||
|
||||
ifeq "$(BUILD)" "exef"
|
||||
LINK=$(PRG_LINK)
|
||||
else
|
||||
LINK=$(LIB_LINK)
|
||||
endif
|
||||
|
||||
# Build rules
|
||||
|
||||
all: preproc start dir $(ALL_OBJ) #prtdebug
|
||||
@echo Linking :$(OUTFILE)
|
||||
ifeq "$(CCFLAG_SWITCH)" "off"
|
||||
@$(LINK)
|
||||
else
|
||||
$(LINK)
|
||||
endif
|
||||
@$(POSTPROC_CMD)
|
||||
@echo -e "\n================================================================================\n"
|
||||
|
||||
sinclude $(DEPENDS)
|
||||
|
||||
release : CC_COMPILE =$(CC) $(RELEASE_CFLAGS) -c $< -o $@
|
||||
release : CC_PRG_LINK=$(CC) $(RELEASE_LINK_CFLAGS) $(OUTFILE) $(ALL_OBJ) $(MODULE_APP_LIB) $(MODULE_PLT_LIB) $(LIB_ADD)
|
||||
release : all
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Make command to use for dependencies
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
MAKE :=make
|
||||
RM :=rm
|
||||
MKDIR :=mkdir
|
||||
|
||||
preproc:
|
||||
@$(PREPROC_CMD)
|
||||
|
||||
start:
|
||||
@echo -e "\n================================================================================\n"
|
||||
@echo "[Building Project]: $(notdir $(MODULE))"
|
||||
ifeq "$(CCFLAG_SWITCH)" "off"
|
||||
@echo "Show Gcc Flags switch = OFF"
|
||||
endif
|
||||
|
||||
prtdebug:
|
||||
@echo "$(MODULE)-$(BUILD)[$(CFG)] build source file:" "$(SRC_FULL_PATH)"
|
||||
@echo SRC_SUBDIR: $(SRC_SUBDIR)
|
||||
@echo SRC_FULL_PATH : $(SRC_FULL_PATH)
|
||||
@echo SRC_FILES : $(SRC_FILES)
|
||||
@echo ALL_OBJ : $(ALL_OBJ)
|
||||
@echo LIB:$(MODULE_PLT_LIB)
|
||||
@echo PLT_LIB: $(PLT_LIB)
|
||||
@echo CCFLAG_SWITCH :$(CCFLAG_SWITCH)
|
||||
|
||||
config: dir
|
||||
|
||||
dir:
|
||||
@$(foreach dir,$(DIRNEED),$(MKDIR) -p $(DIRNEED) --mode=0777; )
|
||||
@$(foreach dir,$(DIRBUILD),$(MKDIR) -p $(dir) --mode=0777; )
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Make Rebuild and clean
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
ifneq "$(PROJ)" ""
|
||||
FRIEND_PROJ := $(shell )
|
||||
endif
|
||||
|
||||
jumprebuild:
|
||||
ifneq "$(PROJ)" ""
|
||||
@cd $(FRIEND_PROJ); mak rebuild ; cd -
|
||||
endif
|
||||
|
||||
# Rebuild this project
|
||||
rebuild: jumprebuild cleanall all
|
||||
|
||||
# Clean this project and all dependencies
|
||||
cleanall: clean
|
||||
|
||||
# Clean this project
|
||||
clean:
|
||||
@echo -e "||--------------------------------------------------------------- "
|
||||
@echo -e "|| Umake clean gcc , lcov, doxygen generated and temporary files. "
|
||||
@echo -e "||--------------------------------------------------------------- "
|
||||
@$(RM) -rf $(OBJDIR) $(OUTFILE) $(COVER_REPORT_PATH) ./doc/doxygen.conf ./doc/html ./doc/latex ./doc/rtf $(foreach dir,$(SRC_SUBDIR),$(dir)/*~)
|
||||
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## indent Makefile.indent
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.indent
|
||||
|
||||
indent:
|
||||
@chmod 777 $(SRC_FULL_PATH)
|
||||
@echo ===================================Indent START=================================
|
||||
@echo
|
||||
@echo "[Indent source file ]: $(SRC_FULL_PATH)"
|
||||
$(call MAKE_INDENT , $(SRC_FULL_PATH))
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## splint makefile.splint
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.splint
|
||||
|
||||
SPLINT_FLAG_SWITCH ?= off
|
||||
|
||||
splint:
|
||||
@chmod 777 $(SRC_FULL_PATH)
|
||||
@echo =================================Splint START==================================
|
||||
@echo
|
||||
ifeq "$(SPLINT_FLAG_SWITCH)" "on"
|
||||
@echo "[Splint flags ]: $(SPLINT_FLAGS)"
|
||||
endif
|
||||
@echo "[Lint Clean Project]: $(notdir $(MODULE))"
|
||||
$(call MAKE_SPLINT, $(SRC_FULL_PATH))
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## doc Makefile.doxygen
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.doxygen
|
||||
|
||||
doc:
|
||||
@chmod 777 $(SRC_FULL_PATH)
|
||||
@echo ==================================Doxygen START=================================
|
||||
@echo
|
||||
$(call MAKE_DOC, $(SRC_FULL_PATH))
|
||||
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## backup Makefile.backup
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.backup
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## cov Makefile.cov
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.cov
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## usage Makefile.usage
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.usage
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Make dependencies
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
$(OBJDIR)/%.d:%.c
|
||||
@$(CC) $< -MM -MD -o $@
|
||||
|
||||
$(OBJDIR)/%.o:%.c
|
||||
|
||||
ifeq "$(CCFLAG_SWITCH)" "off"
|
||||
@echo -e "building: $(notdir $@) \t\t\t\t please wait ..."
|
||||
@$(COMPILE)
|
||||
else
|
||||
$(COMPILE)
|
||||
endif
|
||||
|
||||
DEPENDS=$(COMMON_OBJ:.o=.d)
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Make force
|
||||
##
|
||||
##--------------------------------------
|
||||
FORCE:
|
||||
|
||||
138
proxy_c/dba/src/dba_cfg.c
Normal file
138
proxy_c/dba/src/dba_cfg.c
Normal file
@@ -0,0 +1,138 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "./include/db_adaptor.h"
|
||||
|
||||
#define DBA_CFG "./conf/db_adapotr.cfg"
|
||||
|
||||
_db_cfg db_cfg;
|
||||
|
||||
int dba_read_cfg()
|
||||
{
|
||||
char s[80],s1[80];
|
||||
int len;
|
||||
unsigned char conf_state=0xFF;
|
||||
FILE *fpConf;
|
||||
_db_link *db_ptr=NULL;
|
||||
|
||||
memset(&db_cfg, 0x00, sizeof(_db_cfg));
|
||||
|
||||
fpConf = fopen(DBA_CFG,"rb");
|
||||
|
||||
if(fpConf == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
strcpy(s,"");
|
||||
strcpy(s1,"");
|
||||
while(fgets(s,1024,fpConf) !=(char *)0)
|
||||
{
|
||||
if( (int *)strchr(s,'#') !=NULL) continue;
|
||||
if( !strlen(s) ) continue;
|
||||
len = strlen(s);
|
||||
if(len < 2) continue;
|
||||
|
||||
if(s[len-1] == 0x0d ||s[len-1] == 0x0a)
|
||||
{
|
||||
if(s[len-2] == 0x0d ||s[len-2] == 0x0a)
|
||||
{
|
||||
s[len-2] = 0;
|
||||
len -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
s[len-1] = 0;
|
||||
len -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(!strncasecmp(s,"[db0]",5))
|
||||
{
|
||||
conf_state = 0;
|
||||
db_ptr = &db_cfg.db_link[0];
|
||||
continue;
|
||||
}
|
||||
else if(!strncasecmp(s,"[db1]",5))
|
||||
{
|
||||
conf_state = 1;
|
||||
db_ptr = &db_cfg.db_link[1];
|
||||
continue;
|
||||
}
|
||||
else if(!strncasecmp(s,"[db2]",5))
|
||||
{
|
||||
conf_state = 2;
|
||||
db_ptr = &db_cfg.db_link[2];
|
||||
continue;
|
||||
}
|
||||
else if(!strncasecmp(s,"[db3]",5))
|
||||
{
|
||||
conf_state = 3;
|
||||
db_ptr = &db_cfg.db_link[3];
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(conf_state)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
if(strncasecmp(s,"enable=",7)==0)
|
||||
{
|
||||
if(strncasecmp(&s[7],"on", 2) == 0)
|
||||
db_ptr->enable = 1;
|
||||
else
|
||||
db_ptr->enable = 0;
|
||||
}
|
||||
else if(strncasecmp(s,"role=",5)==0)
|
||||
{
|
||||
db_ptr->role = atoi(&s[5]);
|
||||
}
|
||||
else if(strncasecmp(s,"host_ip=",8)==0)
|
||||
{
|
||||
strcpy(db_ptr->str_host_ip, &s[8]);
|
||||
db_ptr->host_ip = inet_addr(&s[8]);
|
||||
}
|
||||
else if(strncasecmp(s,"host_port=",10)==0)
|
||||
{
|
||||
db_ptr->host_port = atoi(&s[10]);
|
||||
}
|
||||
else if(strncasecmp(s,"db_name=",8)==0)
|
||||
{
|
||||
strcpy(db_ptr->db_name, &s[8]);
|
||||
}
|
||||
else if(strncasecmp(s,"client_name=",12)==0)
|
||||
{
|
||||
strcpy(db_ptr->client_name, &s[12]);
|
||||
}
|
||||
else if(strncasecmp(s,"client_pwd=",11)==0)
|
||||
{
|
||||
strcpy(db_ptr->client_pwd, &s[11]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fpConf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dba_crm_set_prefix_table_created()
|
||||
{
|
||||
db_cfg.prefix_file_created = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dba_crm_get_prefix_table_flag()
|
||||
{
|
||||
return db_cfg.prefix_file_created;
|
||||
}
|
||||
350
proxy_c/dba/src/dba_conn.c
Normal file
350
proxy_c/dba/src/dba_conn.c
Normal file
@@ -0,0 +1,350 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "./include/db_adaptor.h"
|
||||
|
||||
extern _db_cfg db_cfg;
|
||||
|
||||
|
||||
extern char *GetAsciiTime();
|
||||
|
||||
struct timeval tv;
|
||||
|
||||
/*-------------------------------------------------*/
|
||||
|
||||
int dbc_connect_host(u8 db_index)
|
||||
{
|
||||
char host_info[128];
|
||||
_db_link *db_ptr=NULL;
|
||||
unsigned int timeout = 20;
|
||||
MYSQL*tmp_conn = NULL;
|
||||
|
||||
db_ptr = &db_cfg.db_link[db_index];
|
||||
if(db_ptr->enable == 0 || db_ptr->conn_status == 1)
|
||||
return 0;
|
||||
|
||||
if ((db_ptr->db_conn = mysql_init(NULL)) == NULL) {
|
||||
myLOG_D("DBA: mysql_init():failed\n");
|
||||
return -1;
|
||||
}
|
||||
//unsigned int sslmode = SSL_MODE_DISABLED;
|
||||
mysql_options(db_ptr->db_conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&timeout);
|
||||
//mysql_options(db_ptr->db_conn, MYSQL_OPT_SSL_MODE, (const char *)&sslmode);
|
||||
|
||||
sprintf(host_info,"%s", db_ptr->str_host_ip);
|
||||
|
||||
tmp_conn = mysql_real_connect(db_ptr->db_conn, host_info, db_ptr->client_name, db_ptr->client_pwd, db_ptr->db_name, 0, NULL, 0 );
|
||||
|
||||
if(tmp_conn != NULL)
|
||||
{
|
||||
db_ptr->conn_status = 1;
|
||||
db_cfg.total_active_links ++;
|
||||
myLOG_D("DBA: MYSQL connect to SERVER [%d] succeed @%s\n", db_index, GetAsciiTime());
|
||||
}
|
||||
else
|
||||
{
|
||||
db_ptr->conn_status = 0;
|
||||
myLOG_D("DBA: MYSQL connect to SERVER [%d] failed @%s, %s\n", db_index, GetAsciiTime(), mysql_error(db_ptr->db_conn));
|
||||
mysql_close(db_ptr->db_conn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(db_cfg.total_active_links == 1)
|
||||
{
|
||||
db_cfg.current_working_link_id = db_index;
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
MYSQL *dba_get_working_conn(int db_index)
|
||||
{
|
||||
MYSQL *db_conn = NULL;
|
||||
//u8 index = db_cfg.current_working_link_id;
|
||||
u8 index = db_index;
|
||||
|
||||
if(db_cfg.total_active_links == 0)
|
||||
return NULL;
|
||||
if( index < MAX_DB_CONN)
|
||||
{
|
||||
db_conn = db_cfg.db_link[index].db_conn;
|
||||
}
|
||||
//*db_index = index;
|
||||
return db_conn;
|
||||
}
|
||||
|
||||
int dba_close_conn(int index)
|
||||
{
|
||||
if(index>=MAX_DB_CONN)
|
||||
return 0;
|
||||
|
||||
//mysql_close(db_cfg.db_link[index].db_conn);
|
||||
//free(db_cfg.db_link[index].db_conn);
|
||||
|
||||
db_cfg.db_link[index].conn_status = 0;
|
||||
db_cfg.total_active_links --;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dba_my_ping()
|
||||
{
|
||||
int i;
|
||||
int length;
|
||||
char ping_sql[256]={"Replace" };
|
||||
MYSQL *db_conn;
|
||||
int rc;
|
||||
|
||||
for(i=0; i<MAX_DB_CONN; i++)
|
||||
{
|
||||
if(db_cfg.db_link[i].conn_status == 0)
|
||||
continue;
|
||||
|
||||
db_conn = db_cfg.db_link[i].db_conn;
|
||||
if(db_conn == NULL)
|
||||
continue;
|
||||
|
||||
sprintf(ping_sql, "INSERT INTO %s.tb_ping values(%ld)", db_cfg.db_link[i].db_name, tv.tv_sec);
|
||||
length = strlen(ping_sql);
|
||||
|
||||
rc = mysql_real_query(db_conn, ping_sql, length);
|
||||
if(rc != 0)
|
||||
{
|
||||
myLOG_D("DBA: Server [%d] is down by ping @%s error [errno = %d]: [%s]\n", i, GetAsciiTime(), mysql_errno(db_conn),mysql_error(db_conn));
|
||||
|
||||
dba_close_conn(i);
|
||||
|
||||
if(db_cfg.current_working_link_id == i)
|
||||
{
|
||||
if(db_cfg.db_link[1-i].conn_status == 1) //here only support 2 links
|
||||
{
|
||||
db_cfg.current_working_link_id = 1 - i;
|
||||
}
|
||||
else
|
||||
db_cfg.current_working_link_id = INVALID_DB_LINK_ID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
dba_db_sql_execute_crm(const char *sql, char result[][1024], int MAX_ROWS, int MAX_FIELDS, int dump_flag, FILE *fp)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
return dba_db_sql_execute_real(index, sql, result, MAX_ROWS, MAX_FIELDS, dump_flag, fp);
|
||||
}
|
||||
|
||||
dba_db_sql_execute_ocs(const char *sql, char result[][1024], int MAX_ROWS, int MAX_FIELDS, int dump_flag, FILE *fp)
|
||||
{
|
||||
int index = 1;
|
||||
|
||||
return dba_db_sql_execute_real(index, sql, result, MAX_ROWS, MAX_FIELDS, dump_flag, fp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int dba_db_sql_execute_real(int index, const char *sql, char result[][1024], int MAX_ROWS, int MAX_FIELDS, int dump_flag, FILE *fp)
|
||||
{
|
||||
int rc;
|
||||
int i, rows, fields;
|
||||
u16 length;
|
||||
MYSQL *db_conn;
|
||||
MYSQL_RES *res_ptr;
|
||||
MYSQL_ROW row;
|
||||
|
||||
if(sql == NULL)
|
||||
return 0;
|
||||
|
||||
db_conn = dba_get_working_conn(index);
|
||||
if(db_conn == NULL)
|
||||
return 0;
|
||||
|
||||
if(0)
|
||||
{
|
||||
if(dump_flag != 2)
|
||||
{
|
||||
if(strlen(sql)<256)
|
||||
{
|
||||
myLOG_D(sql);
|
||||
myLOG_D("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
char tmpbuf[512]={""};
|
||||
memcpy(tmpbuf, sql, 256);
|
||||
myLOG_D(tmpbuf);
|
||||
myLOG_D("\n");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
length = strlen(sql);
|
||||
rc = mysql_real_query(db_conn, sql, length);
|
||||
if(rc != 0)
|
||||
{
|
||||
myLOG_D("mysql_real_query error [errno = %d]: [%s]\n",mysql_errno(db_conn),mysql_error(db_conn));
|
||||
dba_close_conn(index);
|
||||
//release_mysql_connection(db_conn);
|
||||
return 0;
|
||||
}
|
||||
if(MAX_ROWS == 0)//update not query
|
||||
return 1;
|
||||
|
||||
res_ptr = mysql_store_result(db_conn);
|
||||
if(res_ptr == NULL)
|
||||
{
|
||||
myLOG_D("mysql_store_result error [errno = %d]: [%s]\n",mysql_errno(db_conn),mysql_error(db_conn));
|
||||
return 0;
|
||||
}
|
||||
|
||||
rows = mysql_num_rows(res_ptr);
|
||||
if(rows == 0)
|
||||
goto empty;
|
||||
|
||||
rows = 0;
|
||||
fields = mysql_num_fields(res_ptr);
|
||||
if(fields > MAX_FIELDS)
|
||||
fields = MAX_FIELDS;
|
||||
while ((row = mysql_fetch_row(res_ptr)))
|
||||
{
|
||||
if(dump_flag == 1)
|
||||
{
|
||||
if(fp != NULL)
|
||||
{
|
||||
for (i = 0; i < fields; i++)
|
||||
{
|
||||
if(i == fields - 1)
|
||||
fprintf(fp, "%s\r\n", row[i]);
|
||||
else
|
||||
fprintf(fp, "%s,", row[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < fields; i++)
|
||||
{
|
||||
if(row[i] == NULL)
|
||||
{
|
||||
result[i][0] = 0;
|
||||
if(0)
|
||||
{
|
||||
fields = 0;
|
||||
rows = 0;
|
||||
goto empty;
|
||||
}
|
||||
}
|
||||
else
|
||||
strcpy(result[i], row[i]);
|
||||
}
|
||||
}
|
||||
if(rows++ >= MAX_ROWS)
|
||||
break;
|
||||
}
|
||||
|
||||
empty:
|
||||
mysql_free_result(res_ptr);
|
||||
|
||||
return rows;//fields;
|
||||
}
|
||||
|
||||
static int sql_query_only_counter = 0;
|
||||
int dba_db_sql_query_only_execute_real(const char *sql, char result[][1024], int MAX_ROWS, int MAX_FIELDS )
|
||||
{
|
||||
int index;
|
||||
_db_link *db_ptr=NULL;
|
||||
|
||||
//load balance for tariff query, db_conn#1/2 always
|
||||
if(sql == NULL)
|
||||
return 0;
|
||||
|
||||
index = sql_query_only_counter%2;
|
||||
sql_query_only_counter ++;
|
||||
|
||||
db_ptr = &db_cfg.db_link[index+1];
|
||||
if(db_ptr->enable == 0 || db_ptr->conn_status == 1)
|
||||
{
|
||||
db_ptr = &db_cfg.db_link[(1-index)+1];
|
||||
if(db_ptr->enable == 0 || db_ptr->conn_status == 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
index = (1-index) + 1;
|
||||
}
|
||||
else
|
||||
index = index + 1;
|
||||
|
||||
return dba_db_sql_execute_real(index, sql, result, MAX_ROWS, MAX_FIELDS, 0, NULL);
|
||||
|
||||
}
|
||||
|
||||
int dba_conn_thread(void *param)
|
||||
{
|
||||
register u32 check_conn_timer = 1;
|
||||
register u32 check_sms_notification_timer = 0;
|
||||
|
||||
db_cfg.current_working_link_id = INVALID_DB_LINK_ID;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
dba_init_tariff_sql();
|
||||
crm_pxy_plan_record_init();
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(check_conn_timer % 1000 == 0)//10s
|
||||
{
|
||||
dbc_connect_host(0);
|
||||
dbc_connect_host(1);
|
||||
//dbc_connect_host(2);
|
||||
|
||||
if(0)
|
||||
dba_my_ping();
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
crm_pxy_plan_record_timer();
|
||||
|
||||
}
|
||||
|
||||
if(dba_crm_get_prefix_table_flag() == 0)
|
||||
{
|
||||
dba_crm_dump_prefix_table_into_file();
|
||||
}
|
||||
|
||||
if(rest_provsioning_enabled())
|
||||
{
|
||||
|
||||
if(check_sms_notification_timer%100 == 0) //1seconds==>2S 100==>200
|
||||
{
|
||||
subs_provisioning_command_process();
|
||||
#if 1//def ENABLE_CRM_REST_AND_Z1
|
||||
sms_notification_process();
|
||||
#endif
|
||||
//dba_crm_scan_bundle_thread(tv.tv_sec);
|
||||
}
|
||||
}
|
||||
|
||||
logWriter_rt();
|
||||
|
||||
check_conn_timer ++;
|
||||
check_sms_notification_timer ++;
|
||||
|
||||
usleep(10000); //10ms
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
1735
proxy_c/dba/src/dba_crm.c
Normal file
1735
proxy_c/dba/src/dba_crm.c
Normal file
File diff suppressed because it is too large
Load Diff
1731
proxy_c/dba/src/dba_crm.c.bak
Normal file
1731
proxy_c/dba/src/dba_crm.c.bak
Normal file
File diff suppressed because it is too large
Load Diff
50
proxy_c/dba/src/dba_main.c
Normal file
50
proxy_c/dba/src/dba_main.c
Normal file
@@ -0,0 +1,50 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "./include/db_adaptor.h"
|
||||
|
||||
extern int dba_conn_thread(void *param);
|
||||
|
||||
int dba_main(int argc, char **argv)
|
||||
{
|
||||
int i=0;
|
||||
pthread_t th[MAX_DB_CONN];
|
||||
u8 param[2];
|
||||
|
||||
dba_read_cfg();
|
||||
logWriter_init();
|
||||
|
||||
i = 0;
|
||||
param[0] = i;
|
||||
if(1)
|
||||
{
|
||||
pthread_create(&th[i],NULL,dba_conn_thread, (void *)param);
|
||||
//pthread_join(th[i],NULL);
|
||||
}
|
||||
else
|
||||
dba_conn_thread(NULL);
|
||||
|
||||
if(0)
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
logWriter_rt();
|
||||
sleep(5);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void dba_init()
|
||||
{
|
||||
dba_read_cfg();
|
||||
logWriter_init();
|
||||
}
|
||||
|
||||
62
proxy_c/dba/src/hmac_md5.c
Normal file
62
proxy_c/dba/src/hmac_md5.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
** hmac_md5 -- implements RFC 2104
|
||||
** This hmac_md5 function requires an OpenSSL-compatible MD5
|
||||
** implementation. There are Public Domain MD5 implementations by Colin
|
||||
** Plumb and by Solar Designer. You probably want to use one of these.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "md5.h"
|
||||
|
||||
|
||||
const int blocksize = 64;
|
||||
const int hashsize = 16;
|
||||
|
||||
|
||||
/*
|
||||
** The computed HMAC will be written to `digest'.
|
||||
** Ensure digest points to hashsize bytes of allocated memory.
|
||||
*/
|
||||
void
|
||||
hmac_md5(unsigned char *text, int textlen, unsigned char *key, int keylen,
|
||||
unsigned char *digest)
|
||||
{
|
||||
int i;
|
||||
MD5_CTX context;
|
||||
unsigned char ipad[blocksize];
|
||||
unsigned char opad[blocksize];
|
||||
|
||||
/* too long keys are replaced by their hash value */
|
||||
if (keylen > blocksize) {
|
||||
MD5_Init(&context);
|
||||
MD5_Update(&context, key, keylen);
|
||||
MD5_Final(digest, &context);
|
||||
key = digest;
|
||||
keylen = hashsize;
|
||||
}
|
||||
|
||||
/* copy the key into the pads */
|
||||
memset(ipad, 0, sizeof(ipad));
|
||||
memcpy(ipad, key, keylen);
|
||||
|
||||
memset(opad, 0, sizeof(opad));
|
||||
memcpy(opad, key, keylen);
|
||||
|
||||
/* xor the pads with their ``basic'' value */
|
||||
for (i=0; i<blocksize; i++) {
|
||||
ipad[i] ^= 0x36;
|
||||
opad[i] ^= 0x5c;
|
||||
}
|
||||
|
||||
/* inner pass (ipad ++ message) */
|
||||
MD5_Init(&context);
|
||||
MD5_Update(&context, ipad, sizeof(ipad));
|
||||
MD5_Update(&context, text, textlen);
|
||||
MD5_Final(digest, &context);
|
||||
|
||||
/* outer pass (opad ++ result of inner pass) */
|
||||
MD5_Init(&context);
|
||||
MD5_Update(&context, opad, sizeof(opad));
|
||||
MD5_Update(&context, digest, hashsize);
|
||||
MD5_Final(digest, &context);
|
||||
}
|
||||
47
proxy_c/dba/src/include/db_adaptor.h
Normal file
47
proxy_c/dba/src/include/db_adaptor.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef __DB_ADAPTOR_H
|
||||
#define __DB_ADAPTOR_H
|
||||
|
||||
#include "mysql.h"
|
||||
#include "errmsg.h"
|
||||
#include <dirent.h>
|
||||
|
||||
#ifndef _T_TYPE
|
||||
#define _T_TYPE
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long DWORD;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
#endif
|
||||
|
||||
#define MAX_DB_CONN 4
|
||||
#define DB_NAME_LEN 32
|
||||
#define DB_PWD_LEN 16
|
||||
#define INVALID_DB_LINK_ID 0xFF
|
||||
|
||||
typedef struct db_link
|
||||
{
|
||||
u8 enable;
|
||||
u8 role; /*1=master, 0=slave */
|
||||
u8 conn_status; /*0=not connected, 1=connected */
|
||||
char str_host_ip[16];
|
||||
u32 host_ip;
|
||||
u16 host_port;
|
||||
char db_name[DB_NAME_LEN];
|
||||
char client_name[DB_NAME_LEN];
|
||||
char client_pwd[DB_PWD_LEN];
|
||||
MYSQL *db_conn;
|
||||
}_db_link;
|
||||
|
||||
typedef struct db_cfg
|
||||
{
|
||||
u8 total_active_links;
|
||||
u8 current_working_link_id;
|
||||
u8 prefix_file_created;
|
||||
_db_link db_link[MAX_DB_CONN];
|
||||
}_db_cfg;
|
||||
|
||||
|
||||
#endif
|
||||
201
proxy_c/dba/src/logWrite.c
Normal file
201
proxy_c/dba/src/logWrite.c
Normal file
@@ -0,0 +1,201 @@
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <termio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/io.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
static int new_file_flag = 1;
|
||||
static char system_name[128]="dba";
|
||||
static char log_file_name[256] = {0};
|
||||
static char log_path[256]="/var/log";
|
||||
static int log_max_files=100;
|
||||
static int max_file_size=10240; //10M
|
||||
|
||||
FILE *logFile_fp = NULL;
|
||||
|
||||
|
||||
void logWriter_read_param()
|
||||
{
|
||||
char cnf_file[]="./conf/logWriter.conf";
|
||||
char info_str[512], *buf_ptr;;
|
||||
FILE *fp=NULL;
|
||||
|
||||
fp = fopen(cnf_file,"r");
|
||||
|
||||
|
||||
if(fp == NULL)
|
||||
return;
|
||||
|
||||
while (!feof(fp))
|
||||
{
|
||||
info_str[0] = '\n';
|
||||
fgets(info_str, 500, fp);
|
||||
if (info_str[0] == '#' || info_str[0] == '\n')
|
||||
continue;
|
||||
buf_ptr = info_str;
|
||||
|
||||
if(!strncasecmp(info_str,"sysName=",8))
|
||||
{
|
||||
strsep(&(buf_ptr), "=\n");
|
||||
snprintf(system_name, sizeof(system_name), "%s", strsep(&(buf_ptr), "=\n") );
|
||||
}
|
||||
if(!strncasecmp(info_str,"logPath=",8))
|
||||
{
|
||||
strsep(&(buf_ptr), "=\n");
|
||||
snprintf(log_path, sizeof(log_path), "%s", strsep(&(buf_ptr), "=\n") );
|
||||
}
|
||||
if(!strncasecmp(info_str,"logMaxFiles=",12))
|
||||
{
|
||||
log_max_files = atoi(&info_str[12]);
|
||||
if ( log_max_files > 500 )
|
||||
{
|
||||
log_max_files = 500;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(!strncasecmp(info_str,"logMaxFileSize(KB)=",19))
|
||||
{
|
||||
max_file_size = atoi(&info_str[19]);
|
||||
// Set the min file size to 100KB to control the CPU loading
|
||||
if (max_file_size < 100)
|
||||
{
|
||||
max_file_size = 100;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
printf(" sysName = %s\n logPath = %s\n logMaxFiles = %d\n logMaxFileSize(KB) = %d\n", \
|
||||
system_name, log_path, log_max_files, max_file_size);
|
||||
}
|
||||
|
||||
|
||||
int logWriter_init()
|
||||
{
|
||||
|
||||
logWriter_read_param();
|
||||
|
||||
if(access(log_path,0) == -1 )
|
||||
{
|
||||
if (mkdir(log_path,0777))
|
||||
{
|
||||
printf("creat log_path %s failed!!!", log_path );
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(log_file_name, sizeof(log_file_name), "%s/%s.log", log_path, system_name);
|
||||
logFile_fp = fopen ( log_file_name, "a" );
|
||||
|
||||
printf("logWriter Init Complete!\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int logWriter_write_log_to_disk(char *log_record)
|
||||
{
|
||||
short len;
|
||||
if(log_record == NULL)
|
||||
return 0;
|
||||
|
||||
len = strlen(log_record);
|
||||
fwrite ( log_record, len, 1, logFile_fp );
|
||||
fflush ( logFile_fp ); // force to write to harddisk
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int myLOG_D( const char *fmt, ...)
|
||||
{
|
||||
va_list apa;
|
||||
char buf[10240];
|
||||
//return 0;
|
||||
va_start(apa, fmt);
|
||||
vsprintf(buf, fmt, apa);
|
||||
va_end(apa);
|
||||
|
||||
logWriter_write_log_to_disk(buf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void logWriter_rename_log_file()
|
||||
{
|
||||
int i;
|
||||
char old_file_name[256], new_file_name[256];
|
||||
|
||||
if (log_max_files == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for ( i=(log_max_files-1); i>0; i-- )
|
||||
{
|
||||
snprintf(old_file_name, sizeof(old_file_name), "%s/%s.log.%d", log_path, system_name, i);
|
||||
if (1 == i)
|
||||
{
|
||||
snprintf(new_file_name, sizeof(new_file_name), "%s/%s.log", log_path, system_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(new_file_name, sizeof(new_file_name), "%s/%s.log.%d", log_path, system_name, (i-1) );
|
||||
}
|
||||
if ( access(new_file_name, R_OK) == 0 )
|
||||
{
|
||||
rename(new_file_name, old_file_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int logWriter_rt()
|
||||
{
|
||||
struct stat buf;
|
||||
char real_path[128];
|
||||
|
||||
if (log_file_name[0] != 0)
|
||||
{
|
||||
realpath(log_file_name, real_path);
|
||||
stat(real_path, &buf);
|
||||
if ( buf.st_size >= (max_file_size*1024) )
|
||||
{
|
||||
new_file_flag = 1;
|
||||
logWriter_rename_log_file();
|
||||
}
|
||||
}
|
||||
|
||||
if ( 1 == new_file_flag )
|
||||
{
|
||||
if (logFile_fp != NULL)
|
||||
{
|
||||
fclose ( logFile_fp );
|
||||
logFile_fp = NULL;
|
||||
}
|
||||
logFile_fp = fopen ( log_file_name, "a" );
|
||||
new_file_flag = 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//int main(int argc, char **argv)
|
||||
//{
|
||||
// logWriter_init();
|
||||
//
|
||||
// while(1)
|
||||
// {
|
||||
// logWriter_rt();
|
||||
// usleep(10);
|
||||
// }
|
||||
//
|
||||
// return 1;
|
||||
//}
|
||||
188
proxy_c/dba/src/plan_record.c
Normal file
188
proxy_c/dba/src/plan_record.c
Normal file
@@ -0,0 +1,188 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned short u16;
|
||||
|
||||
#define PLAN_RECORDS 60000
|
||||
#define INVALID_PLAN_INDEX 0xFFFFFFFF
|
||||
|
||||
typedef struct plan_record
|
||||
{
|
||||
u32 index;
|
||||
u8 used_flag;
|
||||
u32 plan_id;
|
||||
u32 updated_time;
|
||||
}__attribute__((packed)) _plan_record;
|
||||
|
||||
typedef struct plan_table
|
||||
{
|
||||
u32 record_num;
|
||||
u32 cur_index;
|
||||
_plan_record plan_record[PLAN_RECORDS+1];
|
||||
}__attribute__((packed)) _plan_table;
|
||||
|
||||
/* ------------ Variables --------------*/
|
||||
static GHashTable *htb_plan = NULL;
|
||||
|
||||
static _plan_table plan_table;
|
||||
|
||||
extern struct timeval tv;
|
||||
|
||||
/* ------------ resouce functions --------------*/
|
||||
|
||||
void free_mem(gpointer data)
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
|
||||
int crm_pxy_init_hash_table()
|
||||
{
|
||||
|
||||
if(htb_plan != NULL)
|
||||
g_hash_table_destroy(htb_plan);
|
||||
|
||||
htb_plan = g_hash_table_new(g_direct_hash,g_direct_equal);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int hash_add_plan_entity(_plan_record *plan_ptr)
|
||||
{
|
||||
if(plan_ptr != NULL)
|
||||
g_hash_table_insert(htb_plan, GINT_TO_POINTER(plan_ptr->plan_id), plan_ptr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int hash_clean_plan_entity(_plan_record *plan_ptr)
|
||||
{
|
||||
if(plan_ptr != NULL)
|
||||
g_hash_table_remove(htb_plan, GINT_TO_POINTER(plan_ptr->plan_id));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int crm_pxy_get_plan_index(u32 plan_id)
|
||||
{
|
||||
u32 index = INVALID_PLAN_INDEX;
|
||||
_plan_record *ptr=NULL;
|
||||
|
||||
ptr = (_plan_record *)g_hash_table_lookup(htb_plan, GINT_TO_POINTER(plan_id));
|
||||
if(ptr != NULL)
|
||||
index = ptr->index;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
int crm_pxy_get_plan_record(u32 plan_id, _plan_record *plan_ptr)
|
||||
{
|
||||
u32 index = crm_pxy_get_plan_index(plan_id);
|
||||
|
||||
return index;
|
||||
|
||||
if(index != INVALID_PLAN_INDEX)
|
||||
{
|
||||
plan_ptr = &plan_table.plan_record[index];
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
_plan_record *crm_pxy_assign_plan_index(u32 plan_id)
|
||||
{
|
||||
register int loop;
|
||||
int index;
|
||||
_plan_record *plan_ptr;
|
||||
|
||||
for(loop = 0; loop < PLAN_RECORDS; loop++)
|
||||
{
|
||||
index = plan_table.cur_index++;
|
||||
plan_table.cur_index %= PLAN_RECORDS;
|
||||
if(plan_table.plan_record[index].used_flag == 0)
|
||||
{
|
||||
plan_table.record_num ++;
|
||||
|
||||
plan_ptr = &plan_table.plan_record[index];
|
||||
plan_ptr->used_flag = 1;
|
||||
plan_ptr->index = index;
|
||||
plan_ptr->plan_id = plan_id;
|
||||
plan_ptr->updated_time = tv.tv_sec;
|
||||
return plan_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int crm_pxy_purge_plan_record(_plan_record *plan_ptr)
|
||||
{
|
||||
|
||||
hash_clean_plan_entity(plan_ptr);
|
||||
|
||||
plan_ptr->used_flag = 0;
|
||||
plan_table.record_num --;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int crm_pxy_add_plan_record(u32 plan_id)
|
||||
{
|
||||
_plan_record *plan_ptr = NULL;
|
||||
|
||||
plan_ptr = crm_pxy_assign_plan_index(plan_id);
|
||||
|
||||
if(plan_ptr == NULL)
|
||||
return 0;
|
||||
|
||||
hash_add_plan_entity(plan_ptr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int crm_pxy_check_plan_record(u32 plan_id)
|
||||
{
|
||||
u32 index = crm_pxy_get_plan_index(plan_id);
|
||||
|
||||
if(index != INVALID_PLAN_INDEX)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void crm_pxy_plan_record_init()
|
||||
{
|
||||
crm_pxy_init_hash_table();
|
||||
}
|
||||
|
||||
static int EXPIRED_TIME_SEC = (86400)*(15);
|
||||
|
||||
void crm_pxy_plan_record_timer()
|
||||
{
|
||||
static int crm_pxy_scan_ptr=0;
|
||||
int i;
|
||||
_plan_record *plan_ptr = NULL;
|
||||
|
||||
for(i=0; i<1000; i++)
|
||||
{
|
||||
plan_ptr = &plan_table.plan_record[crm_pxy_scan_ptr++];
|
||||
crm_pxy_scan_ptr %= PLAN_RECORDS;
|
||||
|
||||
if(plan_ptr->used_flag == 1)
|
||||
{
|
||||
if((plan_ptr->updated_time + EXPIRED_TIME_SEC)<tv.tv_sec)
|
||||
hash_clean_plan_entity(plan_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
102
proxy_c/log.c
Normal file
102
proxy_c/log.c
Normal file
@@ -0,0 +1,102 @@
|
||||
#include "log.h"
|
||||
#include "common.h"
|
||||
|
||||
|
||||
struct log_s g_log_env;
|
||||
|
||||
int log_print(int index)
|
||||
{
|
||||
char file_name[200];
|
||||
char now_time[12];
|
||||
|
||||
if(index == 0)
|
||||
{
|
||||
g_log_env.log_flag = 1;
|
||||
GetCurrentTime(now_time);
|
||||
|
||||
sprintf(file_name, "%s_%02d_%02d_%02d_%02d_%02d_%02d.log",
|
||||
g_log_env.log_file,
|
||||
now_time[0],
|
||||
now_time[1],
|
||||
now_time[2],
|
||||
now_time[3],
|
||||
now_time[4],
|
||||
now_time[5]);
|
||||
g_log_env.log_fp = fopen(file_name, "a+");
|
||||
if(g_log_env.log_fp != NULL)
|
||||
{
|
||||
fprintf(g_log_env.log_fp, "Rest Proxy: Start @%s\r\n", GetAsciiTime());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(g_log_env.log_fp != NULL)
|
||||
fclose(g_log_env.log_fp);
|
||||
|
||||
GetCurrentTime(now_time);
|
||||
|
||||
sprintf(file_name, "%s_%02d_%02d_%02d_%02d_%02d_%02d.log", g_log_env.log_file,
|
||||
now_time[0],
|
||||
now_time[1],
|
||||
now_time[2],
|
||||
now_time[3],
|
||||
now_time[4],
|
||||
now_time[5]);
|
||||
g_log_env.log_fp = fopen(file_name, "a+");
|
||||
if(g_log_env.log_fp != NULL)
|
||||
{
|
||||
fprintf(g_log_env.log_fp, "< Log file opened @%s >\r\n", GetAsciiTime());
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rest_proxy_open_log(int index)
|
||||
{
|
||||
char file_name[200];
|
||||
char now_time[12];
|
||||
|
||||
if(index == 0)
|
||||
{
|
||||
g_log_env.log_flag = 1;
|
||||
GetCurrentTime(now_time);
|
||||
|
||||
sprintf(file_name, "%s_%02d_%02d_%02d_%02d_%02d_%02d.log",
|
||||
g_log_env.log_file,
|
||||
now_time[0],
|
||||
now_time[1],
|
||||
now_time[2],
|
||||
now_time[3],
|
||||
now_time[4],
|
||||
now_time[5]);
|
||||
g_log_env.log_fp = fopen(file_name, "a+");
|
||||
if(g_log_env.log_fp != NULL)
|
||||
{
|
||||
fprintf(g_log_env.log_fp, "Rest Proxy: Start @%s\r\n", GetAsciiTime());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(g_log_env.log_fp != NULL)
|
||||
fclose(g_log_env.log_fp);
|
||||
|
||||
GetCurrentTime(now_time);
|
||||
|
||||
sprintf(file_name, "%s_%02d_%02d_%02d_%02d_%02d_%02d.log", g_log_env.log_file,
|
||||
now_time[0],
|
||||
now_time[1],
|
||||
now_time[2],
|
||||
now_time[3],
|
||||
now_time[4],
|
||||
now_time[5]);
|
||||
g_log_env.log_fp = fopen(file_name, "a+");
|
||||
if(g_log_env.log_fp != NULL)
|
||||
{
|
||||
fprintf(g_log_env.log_fp, "< Log file opened @%s >\r\n", GetAsciiTime());
|
||||
}
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
60
proxy_c/log.h
Normal file
60
proxy_c/log.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#ifndef _LOG_H__
|
||||
#define _LOG_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "rest_proxy.h"
|
||||
|
||||
|
||||
|
||||
struct log_s
|
||||
{
|
||||
int log_flag; /* log information */
|
||||
char log_file[128];
|
||||
FILE *log_fp;
|
||||
unsigned int log_nums;
|
||||
};
|
||||
|
||||
extern struct log_s g_log_env;
|
||||
|
||||
|
||||
#define LOG_D(...) \
|
||||
do{ \
|
||||
if(g_log_env.log_flag) \
|
||||
{ \
|
||||
g_log_env.log_nums ++; \
|
||||
fprintf(g_log_env.log_fp, __VA_ARGS__); \
|
||||
printf( __VA_ARGS__); \
|
||||
fflush(g_log_env.log_fp); \
|
||||
if(g_log_env.log_nums % 2000000==0) \
|
||||
log_print(1); \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
|
||||
#define LOG_E(...) \
|
||||
do{ \
|
||||
if(g_log_env.log_flag) \
|
||||
{ \
|
||||
g_log_env.log_nums ++; \
|
||||
fprintf(g_log_env.log_fp, __VA_ARGS__); \
|
||||
printf( __VA_ARGS__); \
|
||||
fflush(g_log_env.log_fp); \
|
||||
if(g_log_env.log_nums % 2000000==0) \
|
||||
log_print(1); \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
|
||||
int log_print(int index);
|
||||
|
||||
int rest_proxy_open_log(int index);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
198
proxy_c/main.c
Normal file
198
proxy_c/main.c
Normal file
@@ -0,0 +1,198 @@
|
||||
#include "rest_proxy.h"
|
||||
#include "selfcare_proxy.h"
|
||||
#include "log.h"
|
||||
|
||||
int sys_timer10ms;
|
||||
static int proxy_run_mode = 0;
|
||||
// <20><><EFBFBD><EFBFBD>ģʽ
|
||||
#define RUN_MODE_WITH_ALPOOCS 1 /* alpo_ocs<--restful-->restproxy<--udp-->pps */
|
||||
#define RUN_MODE_WITH_ERSTFUL 2 /* user<------restful-->restproxy<--udp-->ocs */
|
||||
#define RUN_MODE_WITH_CRM 4 /* user<--CRM--restful-->restproxy<--udp-->ocs, recharge card/tariff in CRM */
|
||||
|
||||
extern int dba_main(int argc, char **argv);
|
||||
extern int smcli_client_thread(void *param);
|
||||
extern int pstn_client_thread(void *param);
|
||||
extern void _selfcare_udp_process();
|
||||
extern void _selfcare_res_fsm(void);
|
||||
int get_proxy_run_mode()
|
||||
{
|
||||
return proxy_run_mode;
|
||||
}
|
||||
|
||||
int fsm_debug()
|
||||
{
|
||||
char buf[MAX_BUFFER];
|
||||
|
||||
if(cli_read_cmd(buf) == 0)
|
||||
return 0;
|
||||
if(strncasecmp(buf, "log off", 7) == 0)
|
||||
{
|
||||
g_log_env.log_flag = 0x00;
|
||||
}
|
||||
else if(strncasecmp(buf, "log all", 7) == 0)
|
||||
{
|
||||
g_log_env.log_flag = 0xff;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int init_comm(const int log_flag, const char *log_file)
|
||||
{
|
||||
if(log_flag)
|
||||
{
|
||||
strcpy(g_log_env.log_file, log_file);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(g_log_env.log_file, "./log/log");
|
||||
}
|
||||
|
||||
int ret = rest_proxy_open_log(0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int init_modes(int run_mode, int argc, char **argv)
|
||||
{
|
||||
int ret = SUCCESS;
|
||||
pthread_t tid;
|
||||
|
||||
pthread_create(&tid, NULL, (void *)debug_monitor, NULL);
|
||||
|
||||
if(run_mode == RUN_MODE_WITH_ALPOOCS)
|
||||
{
|
||||
/* <20><>ʼ<EFBFBD><CABC>rest proxy. alpo_ocs<-----restful_http-->rest_proxy<------udp----->pps */
|
||||
ret = rest_proxy_init();
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
return ret;;
|
||||
}
|
||||
}
|
||||
|
||||
if(run_mode == RUN_MODE_WITH_ERSTFUL || run_mode == RUN_MODE_WITH_CRM )
|
||||
{
|
||||
|
||||
pthread_create(&tid, NULL, (void *)smcli_client_thread, NULL);
|
||||
|
||||
pthread_create(&tid, NULL, (void *)pstn_client_thread, NULL);
|
||||
|
||||
if(run_mode == RUN_MODE_WITH_CRM)
|
||||
{
|
||||
dba_main(0, NULL);
|
||||
}
|
||||
|
||||
#if 1//def ENABLE_CRM_REST_AND_Z1
|
||||
/* <20><>ʼ<EFBFBD><CABC>selfcare proxy. self_care<-----restful_http----->rest_proxy<-----udp---->ocs */
|
||||
ret = selfcare_proxy_init(argc, argv);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
return ret;;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void run_modes_fsm(int run_mode)
|
||||
{
|
||||
if(run_mode == RUN_MODE_WITH_ALPOOCS)
|
||||
{
|
||||
rest_proxy_fsm_main();
|
||||
}
|
||||
|
||||
fsm_debug();
|
||||
}
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
int ret;
|
||||
int err_flag = 0;
|
||||
char log_file[128]= {0};
|
||||
int run_mode = RUN_MODE_WITH_ALPOOCS;
|
||||
int log_flag = 0;
|
||||
int daemon_flag = 0;
|
||||
|
||||
struct termios prev_termio;
|
||||
|
||||
|
||||
while ((ret = getopt(argc, argv, "a:d:f:r:e")) != -1)
|
||||
{
|
||||
switch (ret)
|
||||
{
|
||||
case 'd':
|
||||
daemon_flag = 1;
|
||||
break;
|
||||
case 'f':
|
||||
if(optarg != NULL)
|
||||
{
|
||||
log_flag = 1;
|
||||
strcpy(log_file, optarg);
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
if(optarg != NULL)
|
||||
{
|
||||
run_mode = atoi(optarg) ;//== RUN_MODE_WITH_ERSTFUL ? RUN_MODE_WITH_ERSTFUL : RUN_MODE_WITH_ALPOOCS;
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
err_flag = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (err_flag)
|
||||
{
|
||||
printf("Usage: %s -c restproxy [-f /va/log/sgs_log_file.txt] [-d] [-r 1(with alpo ocs))|2(with selfcare)]\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
proxy_run_mode = run_mode;
|
||||
|
||||
if(daemon_flag)
|
||||
{
|
||||
sysDaemonInit();
|
||||
}
|
||||
|
||||
SetTermSignal(&prev_termio, Terminate);
|
||||
SigactionSystem();
|
||||
SetFSMTimer();
|
||||
|
||||
ret = init_comm(log_flag, log_file);
|
||||
if(ret != 0)
|
||||
{
|
||||
goto INITFAIL;
|
||||
}
|
||||
|
||||
ret = init_modes(run_mode, argc, argv);
|
||||
if(ret != 0)
|
||||
{
|
||||
goto INITFAIL;
|
||||
}
|
||||
|
||||
|
||||
sys_timer10ms = 1;
|
||||
while(1)
|
||||
{
|
||||
if(sys_timer10ms)
|
||||
{
|
||||
run_modes_fsm(run_mode);
|
||||
}
|
||||
if(0)
|
||||
{
|
||||
_selfcare_udp_process();
|
||||
|
||||
_selfcare_res_fsm();
|
||||
}
|
||||
|
||||
usleep(5000);
|
||||
}
|
||||
|
||||
INITFAIL:
|
||||
rest_proxy_uninit();
|
||||
selfcare_proxy_uninit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
234
proxy_c/mini_cli.c
Normal file
234
proxy_c/mini_cli.c
Normal file
@@ -0,0 +1,234 @@
|
||||
#include "common.h"
|
||||
#include "rest_proxy.h"
|
||||
|
||||
#define DEBUG_PORT 4865
|
||||
|
||||
static int sockfd = 0;
|
||||
static int client_fd = -1;
|
||||
|
||||
extern int init_socket(unsigned int local_addr, short local_port, char stype, int noblock_flag);
|
||||
extern int setnodelay(int fd);
|
||||
extern int printf_stat(FILE *fd);
|
||||
extern int reset_data_sn();
|
||||
|
||||
extern void rest_proxy_print_stat();
|
||||
extern int dba_verify_vc_with_pwd(const char *vc_pwd, char card_info[][1024], char *enc_password);
|
||||
extern int dba_db_sql_query_only_execute_real(const char *sql, char result[][1024], int MAX_ROWS, int MAX_FIELDS );
|
||||
extern void crm_set_notificaton_flag(int flag);
|
||||
extern void crm_set_test_mode_flag(int flag);
|
||||
|
||||
char cli_cmd[128];
|
||||
int cli_cmd_len = 0;
|
||||
int cli_read_cmd(char *buf)
|
||||
{
|
||||
int len = cli_cmd_len;
|
||||
|
||||
if(len>0)
|
||||
strcpy(buf, cli_cmd);
|
||||
cli_cmd_len = 0;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int cli_send_debug(char *buf)
|
||||
{
|
||||
if(buf != NULL)
|
||||
send(client_fd,buf,strlen(buf),MSG_NOSIGNAL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int save_cli_cmd(char *cmd)
|
||||
{
|
||||
strcpy(cli_cmd, cmd);
|
||||
cli_cmd_len = strlen(cmd);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef TEST_RESTPROXY
|
||||
extern int g_pps_sendquery_to_restproxy_num;
|
||||
extern int g_pps_sendtopup_to_restproxy_num;
|
||||
extern int g_pps_sendtrans_to_restproxy_num;
|
||||
#endif
|
||||
int recv_command()
|
||||
{
|
||||
int i = 0;
|
||||
socklen_t server_addr_len = 0;
|
||||
int nbytes/*, len*/;
|
||||
struct sockaddr_in sin;
|
||||
char buf[128],cmd;
|
||||
FILE *fp = NULL;
|
||||
|
||||
// len = sizeof(struct sockaddr);
|
||||
|
||||
nbytes = recvfrom(client_fd, buf, 128, 0,(struct sockaddr *) &sin, &server_addr_len);
|
||||
if(nbytes == 0)
|
||||
{
|
||||
client_fd = -1;
|
||||
return 0;
|
||||
}
|
||||
if(nbytes < 0)
|
||||
return 0;
|
||||
|
||||
if(toupper(buf[0]) == 'Q')
|
||||
{
|
||||
close(client_fd);
|
||||
client_fd = -1;
|
||||
return 0;
|
||||
}
|
||||
save_cli_cmd(buf);
|
||||
// send(client_fd,">",1,MSG_NOSIGNAL);
|
||||
// return 1;
|
||||
for(i = 0; i < nbytes; ++i)
|
||||
{
|
||||
if(buf[i] == '\r' && buf[i+1] == '\n')
|
||||
{
|
||||
buf[i] = '\0';
|
||||
}
|
||||
}
|
||||
if(strncasecmp(buf, "test query", 10) == 0)
|
||||
{
|
||||
send(client_fd, ">test query OK!\n", 16, MSG_NOSIGNAL);
|
||||
|
||||
#ifdef TEST_RESTPROXY
|
||||
if(!g_pps_sendquery_to_restproxy_num)
|
||||
g_pps_sendquery_to_restproxy_num = atoi(&buf[11]);
|
||||
#endif
|
||||
goto END;
|
||||
}
|
||||
if(strncasecmp(buf, "test topup", 10) == 0)
|
||||
{
|
||||
send(client_fd, ">test topup OK!\n", 16, MSG_NOSIGNAL);
|
||||
#ifdef TEST_RESTPROXY
|
||||
if(!g_pps_sendtopup_to_restproxy_num)
|
||||
g_pps_sendtopup_to_restproxy_num = atoi(&buf[11]);
|
||||
#endif
|
||||
goto END;
|
||||
}
|
||||
if(strncasecmp(buf, "test transfer", 13) == 0)
|
||||
{
|
||||
send(client_fd, ">test transfer OK!\n", 19, MSG_NOSIGNAL);
|
||||
#ifdef TEST_RESTPROXY
|
||||
if(!g_pps_sendtrans_to_restproxy_num)
|
||||
g_pps_sendtrans_to_restproxy_num = atoi(&buf[14]);
|
||||
#endif
|
||||
goto END;
|
||||
}
|
||||
if(strncasecmp(buf, "emu enable=", 11) == 0)
|
||||
{
|
||||
int ivalue = atoi(&buf[11]);
|
||||
if(ivalue == 0)
|
||||
send(client_fd, ">Disable Emulator, OK!\n", 23, MSG_NOSIGNAL);
|
||||
else
|
||||
send(client_fd, ">Enable Emulator, OK!\n", 22, MSG_NOSIGNAL);
|
||||
rest_conf_set_emulator_flag(ivalue);
|
||||
goto END;
|
||||
}
|
||||
if(strncasecmp(buf, "get stat", 8) == 0)
|
||||
{
|
||||
rest_proxy_print_stat();
|
||||
|
||||
send(client_fd, ">get stat OK!\n", 15, MSG_NOSIGNAL);
|
||||
goto END;
|
||||
}
|
||||
if(strncasecmp(buf, "test card=", 10) == 0)
|
||||
{
|
||||
dba_verify_vc_with_pwd(&buf[10], NULL, NULL);
|
||||
|
||||
send(client_fd, ">get stat OK!\n", 15, MSG_NOSIGNAL);
|
||||
goto END;
|
||||
}
|
||||
if(strncasecmp(buf, "test query", 10) == 0)
|
||||
{
|
||||
char sql[4096]="select * from tb_sms_info limt 1";
|
||||
char result[30][1024];
|
||||
dba_db_sql_query_only_execute_real(sql, result, 1, 30);
|
||||
|
||||
send(client_fd, ">test tariff query OK!\n", 15, MSG_NOSIGNAL);
|
||||
|
||||
goto END;
|
||||
}
|
||||
if(strncasecmp(buf, "enable notification", 19) == 0)
|
||||
{
|
||||
crm_set_notificaton_flag(1);
|
||||
goto END;
|
||||
}
|
||||
if(strncasecmp(buf, "disable notification", 20) == 0)
|
||||
{
|
||||
crm_set_notificaton_flag(0);
|
||||
goto END;
|
||||
}
|
||||
if(strncasecmp(buf, "test mode=", 10) == 0)
|
||||
{
|
||||
crm_set_test_mode_flag((int)(buf[10]));
|
||||
|
||||
send(client_fd, ">set test mode OK!\n", 15, MSG_NOSIGNAL);
|
||||
goto END;
|
||||
}
|
||||
|
||||
if(nbytes>0)
|
||||
{
|
||||
cmd = toupper(buf[0]);
|
||||
switch(cmd)
|
||||
{
|
||||
case 'P':
|
||||
fp = fopen("stat.txt","w");
|
||||
// printf_stat(fp);
|
||||
send(client_fd,">OK!\n",4,MSG_NOSIGNAL);
|
||||
fclose(fp);
|
||||
break;
|
||||
case 'S':
|
||||
send(client_fd,">OK!\n",4,MSG_NOSIGNAL);
|
||||
// reset_data_sn();
|
||||
break;
|
||||
case 'Q':
|
||||
close(client_fd);
|
||||
client_fd = -1;
|
||||
break;
|
||||
/*
|
||||
default:
|
||||
send(client_fd,">UNK CMD!\n",15,MSG_NOSIGNAL);
|
||||
send(client_fd,">",6,MSG_NOSIGNAL);
|
||||
break;
|
||||
*/
|
||||
}
|
||||
send(client_fd,">",1,MSG_NOSIGNAL);
|
||||
}
|
||||
END:
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
int debug_init()
|
||||
{
|
||||
sockfd = init_socket(0, DEBUG_PORT,1,1);
|
||||
listen(sockfd, 2);
|
||||
return 1;
|
||||
}
|
||||
void debug_monitor(void *arg)
|
||||
{
|
||||
prctl(PR_SET_NAME, "debug_monitor");
|
||||
|
||||
socklen_t clilen;
|
||||
struct sockaddr_in cliaddr;
|
||||
|
||||
debug_init();
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(client_fd<0)
|
||||
{
|
||||
client_fd = accept(sockfd,(struct sockaddr *)&cliaddr,&clilen);
|
||||
if(client_fd>0)
|
||||
{
|
||||
setnodelay(client_fd);
|
||||
send(client_fd, ">", 1, MSG_NOSIGNAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
recv_command();
|
||||
}
|
||||
usleep(10000);
|
||||
}
|
||||
}
|
||||
BIN
proxy_c/pkg.tgz
Normal file
BIN
proxy_c/pkg.tgz
Normal file
Binary file not shown.
53
proxy_c/pstn_cli/Makefile
Normal file
53
proxy_c/pstn_cli/Makefile
Normal file
@@ -0,0 +1,53 @@
|
||||
|
||||
MODULE = pstncli
|
||||
TYPE = plat
|
||||
|
||||
DBUG_FLAGS_ADD =
|
||||
RELS_FLAGS_ADD =
|
||||
|
||||
##Default commonly as below
|
||||
|
||||
BUILD = lib
|
||||
CFG = debug
|
||||
|
||||
|
||||
PLT_LIB = -DDEBUG
|
||||
|
||||
APP_LIB =
|
||||
LIB_ADD =
|
||||
|
||||
SRC_PATH = ./src
|
||||
INC_PATH = ./src/include
|
||||
PLT_PATH = ../../plat
|
||||
APP_PATH = ../../mss
|
||||
|
||||
OBJ_ADD =
|
||||
TEST_OBJ_PATH =
|
||||
|
||||
PREPROC_CMD =
|
||||
POSTPROC_CMD =
|
||||
|
||||
##---------------------------------------------------------------------##
|
||||
##--------------------------------------
|
||||
##
|
||||
## Make configuration(Customer define)
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
## CCFLAG_SWITCH = on/off => gcc flag show on/off
|
||||
## COVER_NEED = yes/no => PTF cover report needed
|
||||
## COVER_REPORT_PATH = [path ] => PTF cover report path
|
||||
|
||||
CCFLAG_SWITCH = off
|
||||
COVER_NEED = no
|
||||
COVER_REPORT_PATH = ./output
|
||||
|
||||
##---------------------------------------------------------------------##
|
||||
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## include makefile.rules (Do not change)
|
||||
##
|
||||
##--------------------------------------
|
||||
include ./scripts/Makefile.rules
|
||||
342
proxy_c/pstn_cli/scripts/Makefile.rules
Normal file
342
proxy_c/pstn_cli/scripts/Makefile.rules
Normal file
@@ -0,0 +1,342 @@
|
||||
|
||||
##----------------------------------------------------------##
|
||||
## ##
|
||||
## Universal Makefile Rules ##
|
||||
## ##
|
||||
## Created : Wei Liu 07/03/07 ##
|
||||
## Revision: [Last]Wei Liu 07/07/07 ##
|
||||
## ##
|
||||
##----------------------------------------------------------##
|
||||
|
||||
|
||||
UMAKE_VERSION := V2.0
|
||||
|
||||
##-------------------------------------
|
||||
##
|
||||
## Work Directory : /usr/local/include
|
||||
## Default Target : all
|
||||
##
|
||||
##-------------------------------------
|
||||
default: all
|
||||
.PHONY: all clean rebuild test indent splint doc \
|
||||
dir config check bk lsbk rmbk unzip umakever usage\
|
||||
FORCE
|
||||
.SUFFIXES:
|
||||
|
||||
umakever:
|
||||
@echo "Universal Makefile (UMake) Version: $(UMAKE_VERSION)"
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Makefile CFG defination check
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
ifeq "$(MODULE)" ""
|
||||
$(error Please input the module name (MODULE = )in makefile. )
|
||||
endif
|
||||
|
||||
ifeq "$(CFG)" ""
|
||||
CFG=debug
|
||||
$(warnning No configuration specified for CFG. Defaulting to $(MODULE) - debug. )
|
||||
endif
|
||||
|
||||
ifeq "$(BUILD)" ""
|
||||
BUILD=lib
|
||||
$(warnning No configuration specified for BUILD. Defaulting to create lib$(MODULE).a. )
|
||||
endif
|
||||
|
||||
ifeq "$(SRC_PATH)" ""
|
||||
SRC_PATH=.
|
||||
$(warnning No configuration specified for SRC_PATH. Defaulting to ./. )
|
||||
endif
|
||||
|
||||
COVER_NEED ?= no
|
||||
PLT_PATH ?= ../../plat
|
||||
APP_PATH ?= ../../app
|
||||
TYPE ?= plat
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Gcc Flag for debug or release
|
||||
##
|
||||
##--------------------------------------
|
||||
CC := gcc
|
||||
GCC_CFLAGS := -Wall -MM
|
||||
AR_LINK := ar -r
|
||||
|
||||
RELS_FLAGS_ADD += -DNDEBUG
|
||||
RELEASE_CFLAGS += -g -Wall -I. $(RELS_FLAGS_ADD) -I/usr/include/mysql -L/usr/lib64/mysql -lmysqlclient
|
||||
RELEASE_LINK_CFLAGS = -g $(RELS_FLAGS_ADD) -o
|
||||
DEBUG_CFLAGS += -g -Wall -rdynamic -DDEBUG -I. $(DBUG_FLAGS_ADD) -I/usr/include/mysql -L/usr/lib64/mysql -lmysqlclient -I/usr/include/openssl
|
||||
DEBUG_LINK_CFLAGS = -g -rdynamic -DDEBUG -o
|
||||
|
||||
ifeq "$(COVER_NEED)" "yes"
|
||||
DEBUG_CFLAGS += -fprofile-arcs -ftest-coverage -pg
|
||||
endif
|
||||
|
||||
GCC_CFLAGS=$(DEBUG_CFLAGS)
|
||||
GCC_LINK_CFLAGS=$(DEBUG_LINK_CFLAGS)
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Project setting
|
||||
##
|
||||
##--------------------------------------
|
||||
OBJDIR:=./obj
|
||||
LIBDIR:=./lib
|
||||
UTDIR :=./ut
|
||||
DOCDIR:=./doc
|
||||
DIRBUILD=$(OBJDIR)
|
||||
|
||||
ifeq "$(BUILD)" "lib"
|
||||
BINDIR:=./bin
|
||||
OUTFILE=$(LIBDIR)/lib$(MODULE).a
|
||||
DIRNEED=$(UTDIR) $(DOCDIR)
|
||||
DIRBUILD+=$(LIBDIR)
|
||||
else
|
||||
BINDIR:=.
|
||||
OUTFILE=$(BINDIR)/$(MODULE)
|
||||
DIRNEED=
|
||||
DIRBUILD+=$(BINDIR)
|
||||
endif
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## source , object and dependencies files
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
SRC_SUBDIR := $(shell find $(SRC_PATH) -type d)
|
||||
|
||||
vpath %.c $(SRC_SUBDIR)
|
||||
vpath %.o $(OBJDIR)
|
||||
vpath %.d $(OBJDIR)
|
||||
|
||||
SRC_FULL_PATH = $(foreach dir,$(SRC_SUBDIR),$(wildcard $(dir)/*.c))
|
||||
SRC_FILES = $(foreach file, $(notdir $(SRC_FULL_PATH)) ,$(OBJDIR)/$(file))
|
||||
COMMON_OBJ = $(SRC_FILES:%.c=%.o)
|
||||
|
||||
TEST_OBJ_PATH ?= ../../obj
|
||||
|
||||
TEST_OBJ = $(foreach dir,$(TEST_OBJ_PATH),$(wildcard $(dir)/*.o))
|
||||
|
||||
OBJ=$(COMMON_OBJ) $(OBJ_ADD)
|
||||
ALL_OBJ := $(OBJ) $(TEST_OBJ)
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Lib setting
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
ifeq "$(COVER_NEED)" "yes"
|
||||
LIBCOVER=-lgcov
|
||||
endif
|
||||
|
||||
MODULE_PLT_LIB=$(foreach lib,$(PLT_LIB), -L$(PLT_PATH)/$(lib)/lib/ -l$(lib) )
|
||||
MODULE_PLT_LIB+=-lm
|
||||
|
||||
|
||||
MODULE_APP_LIB=$(foreach lib,$(APP_LIB),-L$(APP_PATH)/$(lib)/lib -l$(lib))
|
||||
|
||||
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Rules
|
||||
##
|
||||
##--------------------------------------
|
||||
CCFLAG_SWITCH ?= off
|
||||
CC_COMPILE =$(CC) $(GCC_CFLAGS) -c $< -o $@
|
||||
CC_PRG_LINK=$(CC) $(GCC_LINK_CFLAGS) $(OUTFILE) $(ALL_OBJ) $(LIBCOVER) $(MODULE_APP_LIB) $(MODULE_PLT_LIB) $(LIB_ADD)
|
||||
CC_LIB_LINK=$(AR_LINK) $(OUTFILE) $(ALL_OBJ)
|
||||
|
||||
COMPILE=$(CC_COMPILE)
|
||||
PRG_LINK=$(CC_PRG_LINK)
|
||||
LIB_LINK=$(CC_LIB_LINK)
|
||||
|
||||
ifeq "$(BUILD)" "exef"
|
||||
LINK=$(PRG_LINK)
|
||||
else
|
||||
LINK=$(LIB_LINK)
|
||||
endif
|
||||
|
||||
# Build rules
|
||||
|
||||
all: preproc start dir $(ALL_OBJ) #prtdebug
|
||||
@echo Linking :$(OUTFILE)
|
||||
ifeq "$(CCFLAG_SWITCH)" "off"
|
||||
@$(LINK)
|
||||
else
|
||||
$(LINK)
|
||||
endif
|
||||
@$(POSTPROC_CMD)
|
||||
@echo -e "\n================================================================================\n"
|
||||
|
||||
sinclude $(DEPENDS)
|
||||
|
||||
release : CC_COMPILE =$(CC) $(RELEASE_CFLAGS) -c $< -o $@
|
||||
release : CC_PRG_LINK=$(CC) $(RELEASE_LINK_CFLAGS) $(OUTFILE) $(ALL_OBJ) $(MODULE_APP_LIB) $(MODULE_PLT_LIB) $(LIB_ADD)
|
||||
release : all
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Make command to use for dependencies
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
MAKE :=make
|
||||
RM :=rm
|
||||
MKDIR :=mkdir
|
||||
|
||||
preproc:
|
||||
@$(PREPROC_CMD)
|
||||
|
||||
start:
|
||||
@echo -e "\n================================================================================\n"
|
||||
@echo "[Building Project]: $(notdir $(MODULE))"
|
||||
ifeq "$(CCFLAG_SWITCH)" "off"
|
||||
@echo "Show Gcc Flags switch = OFF"
|
||||
endif
|
||||
|
||||
prtdebug:
|
||||
@echo "$(MODULE)-$(BUILD)[$(CFG)] build source file:" "$(SRC_FULL_PATH)"
|
||||
@echo SRC_SUBDIR: $(SRC_SUBDIR)
|
||||
@echo SRC_FULL_PATH : $(SRC_FULL_PATH)
|
||||
@echo SRC_FILES : $(SRC_FILES)
|
||||
@echo ALL_OBJ : $(ALL_OBJ)
|
||||
@echo LIB:$(MODULE_PLT_LIB)
|
||||
@echo PLT_LIB: $(PLT_LIB)
|
||||
@echo CCFLAG_SWITCH :$(CCFLAG_SWITCH)
|
||||
|
||||
config: dir
|
||||
|
||||
dir:
|
||||
@$(foreach dir,$(DIRNEED),$(MKDIR) -p $(DIRNEED) --mode=0777; )
|
||||
@$(foreach dir,$(DIRBUILD),$(MKDIR) -p $(dir) --mode=0777; )
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Make Rebuild and clean
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
ifneq "$(PROJ)" ""
|
||||
FRIEND_PROJ := $(shell )
|
||||
endif
|
||||
|
||||
jumprebuild:
|
||||
ifneq "$(PROJ)" ""
|
||||
@cd $(FRIEND_PROJ); mak rebuild ; cd -
|
||||
endif
|
||||
|
||||
# Rebuild this project
|
||||
rebuild: jumprebuild cleanall all
|
||||
|
||||
# Clean this project and all dependencies
|
||||
cleanall: clean
|
||||
|
||||
# Clean this project
|
||||
clean:
|
||||
@echo -e "||--------------------------------------------------------------- "
|
||||
@echo -e "|| Umake clean gcc , lcov, doxygen generated and temporary files. "
|
||||
@echo -e "||--------------------------------------------------------------- "
|
||||
@$(RM) -rf $(OBJDIR) $(OUTFILE) $(COVER_REPORT_PATH) ./doc/doxygen.conf ./doc/html ./doc/latex ./doc/rtf $(foreach dir,$(SRC_SUBDIR),$(dir)/*~)
|
||||
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## indent Makefile.indent
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.indent
|
||||
|
||||
indent:
|
||||
@chmod 777 $(SRC_FULL_PATH)
|
||||
@echo ===================================Indent START=================================
|
||||
@echo
|
||||
@echo "[Indent source file ]: $(SRC_FULL_PATH)"
|
||||
$(call MAKE_INDENT , $(SRC_FULL_PATH))
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## splint makefile.splint
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.splint
|
||||
|
||||
SPLINT_FLAG_SWITCH ?= off
|
||||
|
||||
splint:
|
||||
@chmod 777 $(SRC_FULL_PATH)
|
||||
@echo =================================Splint START==================================
|
||||
@echo
|
||||
ifeq "$(SPLINT_FLAG_SWITCH)" "on"
|
||||
@echo "[Splint flags ]: $(SPLINT_FLAGS)"
|
||||
endif
|
||||
@echo "[Lint Clean Project]: $(notdir $(MODULE))"
|
||||
$(call MAKE_SPLINT, $(SRC_FULL_PATH))
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## doc Makefile.doxygen
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.doxygen
|
||||
|
||||
doc:
|
||||
@chmod 777 $(SRC_FULL_PATH)
|
||||
@echo ==================================Doxygen START=================================
|
||||
@echo
|
||||
$(call MAKE_DOC, $(SRC_FULL_PATH))
|
||||
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## backup Makefile.backup
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.backup
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## cov Makefile.cov
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.cov
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## usage Makefile.usage
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.usage
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Make dependencies
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
$(OBJDIR)/%.d:%.c
|
||||
@$(CC) $< -MM -MD -o $@
|
||||
|
||||
$(OBJDIR)/%.o:%.c
|
||||
|
||||
ifeq "$(CCFLAG_SWITCH)" "off"
|
||||
@echo -e "building: $(notdir $@) \t\t\t\t please wait ..."
|
||||
@$(COMPILE)
|
||||
else
|
||||
$(COMPILE)
|
||||
endif
|
||||
|
||||
DEPENDS=$(COMMON_OBJ:.o=.d)
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Make force
|
||||
##
|
||||
##--------------------------------------
|
||||
FORCE:
|
||||
|
||||
199
proxy_c/pstn_cli/src/include/pstn_client.h
Normal file
199
proxy_c/pstn_cli/src/include/pstn_client.h
Normal file
@@ -0,0 +1,199 @@
|
||||
#ifndef _PSTN_CLIENT_H
|
||||
#define _PSTN_CLIENT_H
|
||||
|
||||
#define MAX_COMMAND_LEN 2048
|
||||
#define MAX_PSTN_PROCS 8
|
||||
#define MSG_TIMER 6000
|
||||
#define MSG_WAIT_TIMER 400
|
||||
#define MSG_WAIT_LTIMER 1600
|
||||
|
||||
#define MAX_SLOTS 100
|
||||
|
||||
|
||||
typedef struct msan_param_t
|
||||
{
|
||||
u_char server_enable;
|
||||
char server_ip[16];
|
||||
u_short server_port;
|
||||
char user_name[16];
|
||||
char password[16];
|
||||
}_msan_param_t;
|
||||
|
||||
typedef struct pair_2_slot_param_t
|
||||
{
|
||||
int used;
|
||||
int pair_group; /* every 64 pairs is a group */
|
||||
int msan_id; /*1/2 */
|
||||
int slot_id; /* paris are mapped to : slot+port */
|
||||
}_pair_2_slot_param_t;
|
||||
|
||||
typedef struct pstn_server_param_t
|
||||
{
|
||||
char local_ip[16];
|
||||
u_short local_port;
|
||||
u_char server_enable;
|
||||
char server_ip[16];
|
||||
u_short server_port;
|
||||
char user_name[16];
|
||||
char password[16];
|
||||
|
||||
int krone_pair_id_in_crm;
|
||||
int ss_entry_id_in_crm;
|
||||
|
||||
_msan_param_t msan[2];
|
||||
_pair_2_slot_param_t pair_slot_info[MAX_SLOTS];
|
||||
|
||||
}_pstn_server_param_t;
|
||||
|
||||
typedef enum PORT_STATE
|
||||
{
|
||||
PS_NULL,
|
||||
PS_CREATE,
|
||||
PS_UPDATE,
|
||||
PS_DELETE,
|
||||
PS_BAR_OUT,
|
||||
PS_UNBAR_OUT,
|
||||
PS_BAR_IN,
|
||||
PS_UNBAR_IN,
|
||||
PS_CREATE_MSAN,
|
||||
PS_DELETE_MSAN,
|
||||
PS_RELEASE,
|
||||
}_PORT_STATE;
|
||||
|
||||
typedef enum PORT_CRT_STATE
|
||||
{
|
||||
PCS_NULL,
|
||||
PCS_INIT,
|
||||
PCS_ECHO,
|
||||
PCS_LOGIN,
|
||||
PCS_PSSWD,
|
||||
PCS_NOGUI,
|
||||
PCS_QUERY_DSTN,
|
||||
PCS_ENTRY,
|
||||
PCS_STATION,
|
||||
PCS_DSTN,
|
||||
PCS_NAME,
|
||||
PCS_SIGNAL,
|
||||
PCS_SIP_USER,
|
||||
PCS_VOIP_GRP,
|
||||
PCS_TOLL,
|
||||
PCS_EXTI,
|
||||
PCS_ACTIVE,
|
||||
PCS_LOGOUT,
|
||||
PCS_LOGOUT_AGAIN,
|
||||
PCS_TRANS_TO_MSAN,
|
||||
// PCS_ENTRY,
|
||||
// PCS_VOIP_GRP,
|
||||
|
||||
PCS_MAX,
|
||||
}_PORT_CRT_STATE;
|
||||
|
||||
typedef enum PORT_UPDATE_STATE
|
||||
{
|
||||
PUS_NULL,
|
||||
PUS_INIT,
|
||||
PUS_LOGIN,
|
||||
PUS_PSSWD,
|
||||
PUS_NOGUI,
|
||||
PUS_DSTN,
|
||||
PUS_TOLL,
|
||||
PUS_LOCKI,
|
||||
PUS_EXTI,
|
||||
PUS_ACTIVATE,
|
||||
PUS_LOGOUT,
|
||||
PUS_MAX,
|
||||
}_PORT_UPDATE_STATE;
|
||||
|
||||
typedef enum PORT_DEL_STATE
|
||||
{
|
||||
PDS_NULL,
|
||||
PDS_INIT,
|
||||
PDS_LOGIN,
|
||||
PDS_PSSWD,
|
||||
PDS_NOGUI,
|
||||
PDS_DSTN,
|
||||
PDS_ENTRY,
|
||||
PDS_DEL,
|
||||
PDS_EXTI,
|
||||
PDS_LOGOUT,
|
||||
PDS_LOGOUT_AGAIN,
|
||||
PDS_MAX,
|
||||
}_PORT_DEL_STATE;
|
||||
|
||||
|
||||
typedef enum MSAN_CRT_STATE
|
||||
{
|
||||
MCS_NULL,
|
||||
MCS_INIT,
|
||||
MCS_ECHO,
|
||||
MCS_LOGIN,
|
||||
MCS_PSSWD,
|
||||
MCS_CREATE,
|
||||
MCS_BRING_UP,
|
||||
MCS_SAVE,
|
||||
MCS_EXIT,
|
||||
MCS_WAIT_EXIT,
|
||||
MCS_MAX,
|
||||
}_MSAN_CRT_STATE;
|
||||
|
||||
typedef enum MSAN_DEL_STATE
|
||||
{
|
||||
MDS_NULL,
|
||||
MDS_INIT,
|
||||
MDS_LOGIN,
|
||||
MDS_PSSWD,
|
||||
MDS_DELETE,
|
||||
MDS_BRING_DOWN,
|
||||
MDS_SAVE,
|
||||
MDS_LOGOUT,
|
||||
MDS_MAX,
|
||||
}_MSAN_DEL_STATE;
|
||||
|
||||
|
||||
|
||||
typedef enum PSTN_PROV_CMD
|
||||
{
|
||||
PC_NULL,
|
||||
PC_CREATE,
|
||||
PC_UPDATE,
|
||||
PC_DELETE,
|
||||
PC_BAR,
|
||||
PC_UNBAR,
|
||||
}_PSTN_PROV_CMD;
|
||||
|
||||
typedef struct pstn_prov_t
|
||||
{
|
||||
int command;
|
||||
long pre_id;
|
||||
char isdn_number[16];
|
||||
char user_name[64];
|
||||
int ss_entry;
|
||||
int krone_pair_id;
|
||||
int msan_id;
|
||||
int msan_slot_id;
|
||||
int msan_slot_port_id;
|
||||
int update_status;
|
||||
}_pstn_prov_t;
|
||||
|
||||
typedef struct pstn_proc_t
|
||||
{
|
||||
char flag;
|
||||
int id;
|
||||
int tcp_port_id;
|
||||
int state;
|
||||
int sub_state;
|
||||
int timer;
|
||||
int dstn_entry;
|
||||
int recv_msg_flag;
|
||||
int msg_len;
|
||||
char recv_msg[MAX_COMMAND_LEN];
|
||||
_pstn_prov_t prov;
|
||||
}_pstn_proc_t;
|
||||
|
||||
|
||||
typedef struct pstn_procs_t
|
||||
{
|
||||
_pstn_proc_t procs[MAX_PSTN_PROCS];
|
||||
}_pstn_procs_t;
|
||||
|
||||
#endif
|
||||
1174
proxy_c/pstn_cli/src/pstn_client.c
Normal file
1174
proxy_c/pstn_cli/src/pstn_client.c
Normal file
File diff suppressed because it is too large
Load Diff
133
proxy_c/pstn_cli/src/tcp_client.c
Normal file
133
proxy_c/pstn_cli/src/tcp_client.c
Normal file
@@ -0,0 +1,133 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
|
||||
#define RES_LENGTH 10240
|
||||
|
||||
static int client_fd=0;
|
||||
static int client_connect_flag = -1;
|
||||
static char server_ip[16];
|
||||
static short server_port;
|
||||
|
||||
int connect_socket(char * server,int serverPort);
|
||||
int send_msg(int sockfd,char * sendBuff);
|
||||
char * recv_msg(int sockfd);
|
||||
int close_socket(int sockfd);
|
||||
|
||||
int init_socketfd()
|
||||
{
|
||||
int sockfd = -1;
|
||||
|
||||
if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0){
|
||||
herror("Init socket error!");
|
||||
}
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
void tcp_init_client_fd()
|
||||
{
|
||||
client_fd = init_socketfd();
|
||||
|
||||
}
|
||||
|
||||
void tcp_connect_server(char *ip, u_short port)
|
||||
{
|
||||
tcp_init_client_fd();
|
||||
|
||||
strcpy(server_ip, ip);
|
||||
server_port = port;
|
||||
client_connect_flag = connect_socket(ip, port);
|
||||
}
|
||||
|
||||
int is_tcp_connected()
|
||||
{
|
||||
return client_connect_flag;
|
||||
}
|
||||
|
||||
/* * ********************************************************/
|
||||
int connect_socket(char * server,int serverPort)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
struct hostent * phost;
|
||||
|
||||
bzero(&addr,sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(serverPort);
|
||||
addr.sin_addr.s_addr = inet_addr(server);
|
||||
|
||||
if(addr.sin_addr.s_addr == INADDR_NONE){
|
||||
phost = (struct hostent*)gethostbyname(server);
|
||||
if(phost==NULL){
|
||||
herror("Init socket s_addr error!");
|
||||
return -1;
|
||||
}
|
||||
addr.sin_addr.s_addr =((struct in_addr*)phost->h_addr)->s_addr;
|
||||
}
|
||||
if(connect(client_fd,(struct sockaddr*)&addr, sizeof(addr))<0)
|
||||
{
|
||||
// perror("Connect server fail!");
|
||||
return -1; //0<><30>ʾ<EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD>-1<><31>ʾʧ<CABE><CAA7>
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int tcp_send_msg( u_char *sendbuf, short len)
|
||||
{
|
||||
int sendSize=0;
|
||||
|
||||
if((sendSize=send(client_fd,sendbuf,len,MSG_NOSIGNAL))<=0){
|
||||
close_socket(client_fd);
|
||||
herror("Send msg error!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sendSize;
|
||||
}
|
||||
|
||||
int tcp_recv_msg(u_char *recvbuf)
|
||||
{
|
||||
int recLenth=0;
|
||||
|
||||
if(( recLenth=recv(client_fd,recvbuf, BUF_SIZE,0))==-1 )
|
||||
{
|
||||
close_socket(client_fd);
|
||||
return -1;
|
||||
}
|
||||
if( recLenth>0)
|
||||
recvbuf[recLenth] = 0;
|
||||
return recLenth;
|
||||
}
|
||||
|
||||
int tcp_check_connection()
|
||||
{
|
||||
//if(client_connect_flag == -1)
|
||||
// connect_socket(server_ip, server_port);
|
||||
|
||||
return client_connect_flag;
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
*<2A>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD>
|
||||
* **********************************************/
|
||||
int close_socket(int sockfd)
|
||||
{
|
||||
client_connect_flag = -1;
|
||||
close(sockfd);
|
||||
|
||||
smcli_connection_is_broken();
|
||||
|
||||
return 0;
|
||||
}
|
||||
1404
proxy_c/rest_proxy.c
Normal file
1404
proxy_c/rest_proxy.c
Normal file
File diff suppressed because it is too large
Load Diff
150
proxy_c/rest_proxy.h
Normal file
150
proxy_c/rest_proxy.h
Normal file
@@ -0,0 +1,150 @@
|
||||
#ifndef __REST_PROXY_H__
|
||||
#define __REST_PROXY_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#include "restapi.h"
|
||||
#include "curl_adaptor.h"
|
||||
#include "rest_proxy_conf.h"
|
||||
|
||||
|
||||
#define HTTP_OK 200
|
||||
|
||||
|
||||
#define SERVER_PORT 4949
|
||||
|
||||
#define WAIT_TIMER 500 //5seconds
|
||||
|
||||
// #define RESTPROXY_MISISDN_LEN 24
|
||||
|
||||
|
||||
#define MAX_THREADS 1024//256
|
||||
|
||||
#define THREAD_INVALID_INDEX 0xFFFF
|
||||
|
||||
typedef enum _STATE
|
||||
{
|
||||
ST_SEND_QUERY_SUBSID = 1,
|
||||
ST_SEND_QUERY,
|
||||
ST_SEND_TOPUP,
|
||||
ST_SEND_TOPUP_SUBSCRIBID,
|
||||
|
||||
ST_SEND_TRANS_SUBSID_SENDER,
|
||||
ST_SEND_TRANS_SUBSID_RECEIVER,
|
||||
ST_SEND_TRANS,
|
||||
ST_WAIT_RESTAPI_TRANS_SUBSID_SENDER,
|
||||
ST_WAIT_RESTAPI_TRANS_SUBID_RECEIVER,
|
||||
ST_WAIT_RESTAPI_TRANS,
|
||||
|
||||
ST_WAIT_RESTAPI,
|
||||
ST_WAIT_RESTAPI_QUERY_SUBSID,
|
||||
ST_WAIT_RESTAPI_TOPUP_SUBID,
|
||||
|
||||
|
||||
}STATE;
|
||||
|
||||
typedef enum _STATISTICS
|
||||
{
|
||||
STAT_QUERY_REQ,
|
||||
STAT_QUERY_RES,
|
||||
STAT_QUERY_REST_SUBSID_REQ, /* <20><><EFBFBD><EFBFBD>subscriber id<69><64><EFBFBD><EFBFBD>ͳ<EFBFBD><CDB3> */
|
||||
STAT_QUERY_REST_SUBSID_RES, /* <20><><EFBFBD><EFBFBD>subscriber id<69>ظ<EFBFBD>ͳ<EFBFBD><CDB3> */
|
||||
STAT_QUERY_REST_REQ,
|
||||
STAT_QUERY_REST_RES,
|
||||
|
||||
STAT_TRANSFER_REQ,
|
||||
STAT_TRANSFER_RES,
|
||||
STAT_TRANSFER_REST_SUBSID_REQ_SENDER,
|
||||
STAT_TRANSFER_REST_SUBSID_RES_SENDER,
|
||||
STAT_TRANSFER_REST_SUBSID_REQ_RECEIVER,
|
||||
STAT_TRANSFER_REST_SUBSID_RES_RECEIVER,
|
||||
STAT_TRANSFER_REST_REQ,
|
||||
STAT_TRANSFER_REST_RES,
|
||||
|
||||
STAT_TOPUP_REQ,
|
||||
STAT_TOPUP_RES,
|
||||
STAT_TOPUP_REST_SUBSID_REQ, /* <20><><EFBFBD><EFBFBD>subscriber id<69><64><EFBFBD><EFBFBD>ͳ<EFBFBD><CDB3> */
|
||||
STAT_TOPUP_REST_SUBSID_RES, /* <20><><EFBFBD><EFBFBD>subscriber id<69>ظ<EFBFBD>ͳ<EFBFBD><CDB3> */
|
||||
STAT_TOPUP_REST_REQ,
|
||||
STAT_TOPUP_REST_RES,
|
||||
|
||||
STAT_MAX,
|
||||
|
||||
}STATISTICS;
|
||||
|
||||
typedef struct rest_thread
|
||||
{
|
||||
char used;
|
||||
char state;
|
||||
int timer;
|
||||
short ppsAppID;
|
||||
short restproxyAppID;
|
||||
char msisdn[RESTFUL_MSISDN_LEN];
|
||||
char pin[RESTFUL_MSISDN_LEN];
|
||||
|
||||
char msisdn_out[RESTFUL_MSISDN_LEN];
|
||||
char msisdn_in[RESTFUL_MSISDN_LEN];
|
||||
u32 money;
|
||||
|
||||
char username[RESTFUL_USERNAME];
|
||||
char password[RESTFUL_PASSWOR];
|
||||
int pps_ip;
|
||||
short pps_port;
|
||||
|
||||
SCurlAdaptor curAdaptor;
|
||||
}_rest_thread;
|
||||
|
||||
typedef struct _s_rest_proxy_env
|
||||
{
|
||||
s_restproxy_conf cnf; /* rest proxy configure infor */
|
||||
|
||||
_rest_thread threads[MAX_THREADS]; /* handle messge from/to pps&rest */
|
||||
|
||||
int work_as_proxy_emulator;
|
||||
|
||||
int query_req_num; /* counts pps<->restproxy<->restful */
|
||||
int query_res_num;
|
||||
int query_rest_subscrib_req_num;
|
||||
int query_rest_subscrib_res_num;
|
||||
int query_rest_req_num;
|
||||
int query_rest_res_num;
|
||||
|
||||
int trans_req_num; /* counts pps<->restproxy<->restful */
|
||||
int trans_res_num;
|
||||
int trans_rest_subscrib_req_num_out;
|
||||
int trans_rest_subscrib_res_num_out;
|
||||
int trans_rest_subscrib_req_num_in;
|
||||
int trans_rest_subscrib_res_num_in;
|
||||
int trans_rest_req_num;
|
||||
int trans_rest_res_num;
|
||||
|
||||
int topup_req_num;
|
||||
int topup_res_num;
|
||||
int topup_rest_subscrib_req_num;
|
||||
int topup_rest_subscrib_res_num;
|
||||
int topup_rest_req_num;
|
||||
int topup_rest_res_num;
|
||||
}s_rest_proxy_env;
|
||||
|
||||
#define REST_PROXY_SUBSCRIBID_FLAG (g_rest_proxy_env.cnf.b_fetch_subscribid)
|
||||
|
||||
extern s_rest_proxy_env g_rest_proxy_env;
|
||||
|
||||
|
||||
int rest_conf_set_emulator_flag(int flag);
|
||||
|
||||
|
||||
int rest_proxy_init();
|
||||
|
||||
void rest_proxy_uninit();
|
||||
|
||||
int rest_proxy_fsm_main();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __REST_PROXY_H__ */
|
||||
132
proxy_c/rest_proxy_conf.c
Normal file
132
proxy_c/rest_proxy_conf.c
Normal file
@@ -0,0 +1,132 @@
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include "rest_proxy_conf.h"
|
||||
|
||||
void rest_proxy_load_conf_ipport(const char* buffer,
|
||||
const char* key,
|
||||
unsigned int* ip,
|
||||
char* ip_str,
|
||||
unsigned short* port)
|
||||
{
|
||||
char buffer_ip[16] = {0};
|
||||
// char buffer_port[4] = {0};
|
||||
char *pos = NULL;
|
||||
char *pos_ip_start = NULL;
|
||||
char *pos_ip_end = NULL;
|
||||
/* first address is start of the line */
|
||||
pos = strstr(buffer, key);
|
||||
if(NULL != pos && buffer == pos)
|
||||
{
|
||||
pos_ip_start = strstr(pos, "=");
|
||||
if(NULL != pos_ip_start)
|
||||
{
|
||||
pos_ip_end = strstr(pos_ip_start + 1, ":");
|
||||
if(NULL != pos_ip_end)
|
||||
{
|
||||
memcpy(buffer_ip, pos_ip_start + 1, (pos_ip_end - 1) - (pos_ip_start + 1) + 1);
|
||||
if(ip_str)
|
||||
{
|
||||
strcpy(ip_str, buffer_ip);
|
||||
}
|
||||
*ip = inet_addr(buffer_ip);
|
||||
*port = atoi(pos_ip_end + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rest_proxy_load_conf_str(const char* buffer, const char* key, char* val)
|
||||
{
|
||||
char *pos = NULL;
|
||||
char *pos_val_start = NULL;
|
||||
/* first address is start of the line */
|
||||
pos = strstr(buffer, key);
|
||||
if(NULL != pos && buffer == pos && buffer[strlen(key)] == '=')
|
||||
{
|
||||
pos_val_start = strstr(pos, "=");
|
||||
|
||||
/* remove \r or \n which first appear */
|
||||
pos = pos_val_start;
|
||||
while(pos)
|
||||
{
|
||||
if(*pos == '\r' || *pos == '\n' || *pos == '\0')
|
||||
break;
|
||||
pos++;
|
||||
}
|
||||
if(pos)
|
||||
*pos = '\0';
|
||||
|
||||
if(NULL != pos_val_start)
|
||||
{
|
||||
strcpy(val, pos_val_start + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
void rest_proxy_load_conf_int(const char* buffer, const char* key, int* val)
|
||||
{
|
||||
char tmp_buf[64] = {0};
|
||||
rest_proxy_load_conf_str(buffer, key, tmp_buf);
|
||||
if(tmp_buf[0] != '\0')
|
||||
{
|
||||
*val = atoi(tmp_buf);
|
||||
}
|
||||
}
|
||||
int rest_proxy_load_cnf(s_restproxy_conf *conf)
|
||||
{
|
||||
#define BUFFER_LEN 1024
|
||||
FILE* fd;
|
||||
char buffer[BUFFER_LEN] = {0};
|
||||
|
||||
if(NULL == conf->cnf_file)
|
||||
{
|
||||
conf->cnf_file = REST_PROXY_DEFAULT_CONF_FILE;
|
||||
}
|
||||
|
||||
/* Create input file descriptor */
|
||||
fd = fopen (conf->cnf_file, "r");
|
||||
if (fd == NULL)
|
||||
{
|
||||
perror ("open");
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Copy process */
|
||||
while((fgets(buffer, BUFFER_LEN, fd)) != NULL)
|
||||
{
|
||||
if(buffer[0] == '#')
|
||||
continue;
|
||||
rest_proxy_load_conf_ipport(buffer, "localIPPort", &conf->local_ip, NULL, &conf->local_port);
|
||||
|
||||
rest_proxy_load_conf_ipport(buffer, "queryIPPort", &conf->query_ip, conf->query_ip_str, &conf->query_port);
|
||||
|
||||
rest_proxy_load_conf_ipport(buffer, "rechargeIPPort", &conf->recharege_ip, conf->recharge_ip_str, &conf->recharge_port);
|
||||
|
||||
#ifdef TEST_RESTPROXY
|
||||
rest_proxy_load_conf_str(buffer, "test_msisdn", conf->msisdn);
|
||||
rest_proxy_load_conf_str(buffer, "test_msisdn_in", conf->msisdn_in);
|
||||
rest_proxy_load_conf_str(buffer, "test_pin", conf->pin);
|
||||
#endif
|
||||
rest_proxy_load_conf_str(buffer, "username", conf->username);
|
||||
rest_proxy_load_conf_str(buffer, "password", conf->password);
|
||||
rest_proxy_load_conf_str(buffer, "subsystem", conf->subsystem);
|
||||
rest_proxy_load_conf_str(buffer, "customerIP", conf->customer_ip);
|
||||
|
||||
rest_proxy_load_conf_str(buffer, "url_walletbalance", conf->url_fetchwalletbalance);
|
||||
rest_proxy_load_conf_str(buffer, "url_rechargevoucher", conf->url_recharge);
|
||||
|
||||
rest_proxy_load_conf_str(buffer, "url_walletbalance_getscriberid", conf->url_fetchwalletbalance_getsubsid);
|
||||
rest_proxy_load_conf_str(buffer, "url_rechargevoucher_getscriberid", conf->url_recharge_getsubsid);
|
||||
rest_proxy_load_conf_int(buffer, "query_topup_getscriberid_switch", &conf->b_fetch_subscribid);
|
||||
|
||||
rest_proxy_load_conf_str(buffer, "url_trans_getsubsid_sender", conf->url_trans_getsubsid_sender);
|
||||
rest_proxy_load_conf_str(buffer, "url_trans_getsubsid_receiver", conf->url_trans_getsubsid_receiver);
|
||||
rest_proxy_load_conf_str(buffer, "url_trans", conf->url_trans);
|
||||
|
||||
memset(buffer, 0x00, BUFFER_LEN);
|
||||
}
|
||||
|
||||
fclose (fd);
|
||||
return 0;
|
||||
}
|
||||
65
proxy_c/rest_proxy_conf.h
Normal file
65
proxy_c/rest_proxy_conf.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifndef __REST_PROXY_CONF_H__
|
||||
#define __REST_PROXY_CONF_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define REST_PROXY_DEFAULT_CONF_FILE "./conf/rest_proxy.conf"
|
||||
|
||||
typedef struct _s_restproxy_conf
|
||||
{
|
||||
const char* cnf_file; /* rest proxy configure name */
|
||||
|
||||
unsigned int local_ip; /* rest proxy host udp ip. host order */
|
||||
unsigned short local_port; /* rest proxy host udp port. host order */
|
||||
int as_server_fd; /* fd when rest proxy as server */
|
||||
|
||||
|
||||
unsigned int query_ip; /* restful http ip. host order */
|
||||
char query_ip_str[24];
|
||||
unsigned short query_port; /* restful http port. host order */
|
||||
|
||||
unsigned int recharege_ip; /* restful http vourchar ip. host order */
|
||||
char recharge_ip_str[24];
|
||||
unsigned short recharge_port; /* restful http vourchar port. host order */
|
||||
|
||||
#ifdef TEST_RESTPROXY
|
||||
char msisdn[24];
|
||||
char msisdn_in[24];
|
||||
char pin[24];
|
||||
#endif
|
||||
char username[24];
|
||||
char password[24];
|
||||
|
||||
|
||||
char subsystem[24];
|
||||
char customer_ip[24];
|
||||
|
||||
int b_fetch_subscribid; /* <20><>ʶquery/recharge <20>Ƿ<EFBFBD><C7B7><EFBFBD>Ҫ<EFBFBD><D2AA>ȡsubscriberID */
|
||||
|
||||
char url_fetchwalletbalance_getsubsid[128];
|
||||
char url_fetchwalletbalance[128];
|
||||
char url_recharge_getsubsid[128];
|
||||
char url_recharge[128];
|
||||
|
||||
char url_trans_getsubsid_sender[128];
|
||||
char url_trans_getsubsid_receiver[128];
|
||||
char url_trans[128];
|
||||
}s_restproxy_conf;
|
||||
|
||||
|
||||
|
||||
int rest_proxy_load_cnf(s_restproxy_conf *conf);
|
||||
|
||||
char *rest_proxy_errcodemsg(const unsigned int errcode);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __REST_PROXY_CONF_H__ */
|
||||
85
proxy_c/rest_proxy_print.c
Normal file
85
proxy_c/rest_proxy_print.c
Normal file
@@ -0,0 +1,85 @@
|
||||
#include "rest_proxy_print.h"
|
||||
#include "rest_proxy.h"
|
||||
#include "log.h"
|
||||
|
||||
|
||||
|
||||
|
||||
void rest_proxy_print_stat()
|
||||
{
|
||||
LOG_D("query: pps->restproxy->rest[%d, %d] response: pps<-restproxy<-rest[%d, %d]\n",
|
||||
g_rest_proxy_env.query_req_num, g_rest_proxy_env.query_rest_req_num,
|
||||
g_rest_proxy_env.query_res_num, g_rest_proxy_env.query_rest_res_num);
|
||||
LOG_D(" get-subscribid: restproxy->rest[%d]\n", g_rest_proxy_env.query_rest_subscrib_req_num);
|
||||
LOG_D(" restproxy<-rest[%d]\n", g_rest_proxy_env.query_rest_subscrib_res_num);
|
||||
|
||||
LOG_D("topup: pps->restproxy->rest[%d, %d] response: pps<-restproxy<-rest[%d, %d]\n",
|
||||
g_rest_proxy_env.topup_req_num, g_rest_proxy_env.topup_rest_req_num,
|
||||
g_rest_proxy_env.topup_res_num, g_rest_proxy_env.topup_rest_res_num);
|
||||
LOG_D(" get-subscribid: restproxy->rest[%d]\n", g_rest_proxy_env.topup_rest_subscrib_req_num);
|
||||
LOG_D(" restproxy<-rest[%d]\n", g_rest_proxy_env.topup_rest_subscrib_res_num);
|
||||
|
||||
LOG_D("trans: pps->restproxy->rest[%d, %d] response: pps<-restproxy<-rest[%d, %d]\n",
|
||||
g_rest_proxy_env.trans_req_num, g_rest_proxy_env.trans_rest_req_num,
|
||||
g_rest_proxy_env.trans_res_num, g_rest_proxy_env.trans_rest_res_num);
|
||||
LOG_D(" get-subscribid_out: restproxy->rest[%d]\n", g_rest_proxy_env.trans_rest_subscrib_req_num_out);
|
||||
LOG_D(" restproxy<-rest[%d]\n", g_rest_proxy_env.trans_rest_subscrib_res_num_out);
|
||||
LOG_D(" get-subscribid_in: restproxy->rest[%d]\n", g_rest_proxy_env.trans_rest_subscrib_req_num_in);
|
||||
LOG_D(" restproxy<-rest[%d]\n", g_rest_proxy_env.trans_rest_subscrib_res_num_in);
|
||||
}
|
||||
void rest_proxy_print_msg(const struct rest_msg_s* msg, int b_is_request, const char* tip)
|
||||
{
|
||||
return ;
|
||||
switch(msg->msg_type)
|
||||
{
|
||||
case REST_QUERY:
|
||||
if(b_is_request)
|
||||
{
|
||||
LOG_D("%s MsgType:%d SrcDstRef[%d, %d] MSISDN:%s\n",
|
||||
tip, msg->msg_type, msg->header.src_ref, msg->header.dst_ref,
|
||||
msg->msg.query.msisdn);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D("%s msgType:%d SrcDstRef[%d, %d] Res:%d ErrCode:%d Balance:%u MOMTExpiry[%u, %u].\n",
|
||||
tip, msg->msg_type, msg->header.src_ref, msg->header.dst_ref,
|
||||
msg->msg.query_res.result, msg->msg.query_res.error_code, msg->msg.query_res.balance,
|
||||
msg->msg.query_res.mo_expiry, msg->msg.query_res.mt_expiry);
|
||||
}
|
||||
break;
|
||||
case REST_TOPUP:
|
||||
if(b_is_request)
|
||||
{
|
||||
LOG_D("%s MsgType:%d SrcDstRef[%d, %d] MSISDN:%s PIN:%s\n",
|
||||
tip, msg->msg_type, msg->header.src_ref, msg->header.dst_ref,
|
||||
msg->msg.topup.msisdn, msg->msg.topup.password);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D("%s msgType:%d SrcDstRef[%d, %d] Res:%d ErrCode:%d Balance:%u MOMTExpiry[%u, %u].\n",
|
||||
tip, msg->msg_type, msg->header.src_ref, msg->header.dst_ref,
|
||||
msg->msg.topup_res.result, msg->msg.topup_res.error_code, msg->msg.topup_res.balance,
|
||||
msg->msg.topup_res.mo_expiry, msg->msg.topup_res.mt_expiry);
|
||||
}
|
||||
break;
|
||||
case REST_TRANSFER:
|
||||
if(b_is_request)
|
||||
{
|
||||
LOG_D("%s MsgType:%d SrcDstRef[%d, %d] MSISDN_OUT:%s MSISDN_IN:%s Money:%d\n",
|
||||
tip, msg->msg_type, msg->header.src_ref, msg->header.dst_ref,
|
||||
msg->msg.transfer.transferOutMsisdn, msg->msg.transfer.transferInMsisdn, msg->msg.transfer.amount);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_D("%s msgType:%d SrcDstRef[%d, %d] Res:%d ErrCode:%d balance:%d\n",
|
||||
tip, msg->msg_type, msg->header.src_ref, msg->header.dst_ref,
|
||||
msg->msg.transfer_res.result, msg->msg.transfer_res.error_code, msg->msg.transfer_res.balance);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* print err msg. Or else? */
|
||||
LOG_D("%s err. msgType:%d\n", __FUNCTION__, msg->msg_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
11
proxy_c/rest_proxy_print.h
Normal file
11
proxy_c/rest_proxy_print.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef __REST_PROXY_PRINT_H__
|
||||
#define __REST_PROXY_PRINT_H__
|
||||
|
||||
#include "restapi.h"
|
||||
|
||||
void rest_proxy_print_stat();
|
||||
|
||||
void rest_proxy_print_msg(const struct rest_msg_s* msg, int b_is_request, const char* tip);
|
||||
|
||||
|
||||
#endif /* __REST_PROXY_PRINT_H__ */
|
||||
83
proxy_c/rest_proxy_stat.c
Normal file
83
proxy_c/rest_proxy_stat.c
Normal file
@@ -0,0 +1,83 @@
|
||||
#include "rest_proxy_stat.h"
|
||||
#include "rest_proxy.h"
|
||||
|
||||
|
||||
/* -------------------------------------*/
|
||||
void rest_proxy_stat_count(int stat_type)
|
||||
{
|
||||
static int *state_count[STAT_MAX];
|
||||
static char b_loaded = 0;
|
||||
if(b_loaded == 0)
|
||||
{
|
||||
state_count[STAT_QUERY_REQ] = &g_rest_proxy_env.query_req_num;
|
||||
state_count[STAT_QUERY_RES] = &g_rest_proxy_env.query_res_num;
|
||||
state_count[STAT_QUERY_REST_SUBSID_REQ] = &g_rest_proxy_env.query_rest_subscrib_req_num;
|
||||
state_count[STAT_QUERY_REST_SUBSID_RES] = &g_rest_proxy_env.query_rest_subscrib_res_num;
|
||||
state_count[STAT_QUERY_REST_REQ] = &g_rest_proxy_env.query_rest_req_num;
|
||||
state_count[STAT_QUERY_REST_RES] = &g_rest_proxy_env.query_rest_res_num;
|
||||
|
||||
state_count[STAT_TOPUP_REQ] = &g_rest_proxy_env.topup_req_num;
|
||||
state_count[STAT_TOPUP_RES] = &g_rest_proxy_env.topup_res_num;
|
||||
state_count[STAT_TOPUP_REST_SUBSID_REQ] = &g_rest_proxy_env.topup_rest_subscrib_req_num;
|
||||
state_count[STAT_TOPUP_REST_SUBSID_RES] = &g_rest_proxy_env.topup_rest_subscrib_res_num;
|
||||
state_count[STAT_TOPUP_REST_REQ] = &g_rest_proxy_env.topup_rest_req_num;
|
||||
state_count[STAT_TOPUP_REST_RES] = &g_rest_proxy_env.topup_rest_res_num;
|
||||
|
||||
state_count[STAT_TRANSFER_REQ] = &g_rest_proxy_env.trans_req_num;
|
||||
state_count[STAT_TRANSFER_RES] = &g_rest_proxy_env.trans_res_num;
|
||||
state_count[STAT_TRANSFER_REST_SUBSID_REQ_SENDER] = &g_rest_proxy_env.trans_rest_subscrib_req_num_out;
|
||||
state_count[STAT_TRANSFER_REST_SUBSID_RES_SENDER] = &g_rest_proxy_env.trans_rest_subscrib_res_num_out;
|
||||
|
||||
state_count[STAT_TRANSFER_REST_SUBSID_REQ_RECEIVER] = &g_rest_proxy_env.trans_rest_subscrib_req_num_in;
|
||||
state_count[STAT_TRANSFER_REST_SUBSID_RES_RECEIVER] = &g_rest_proxy_env.trans_rest_subscrib_res_num_in;
|
||||
state_count[STAT_TRANSFER_REST_REQ] = &g_rest_proxy_env.trans_rest_req_num;
|
||||
state_count[STAT_TRANSFER_REST_RES] = &g_rest_proxy_env.trans_rest_res_num;
|
||||
|
||||
|
||||
b_loaded = 1;
|
||||
}
|
||||
|
||||
(*state_count[stat_type]) += 1;
|
||||
#if 0
|
||||
switch(stat_type)
|
||||
{
|
||||
case STAT_QUERY_REQ:
|
||||
g_rest_proxy_env.query_req_num++;
|
||||
break;
|
||||
case STAT_QUERY_RES:
|
||||
g_rest_proxy_env.query_res_num++;
|
||||
break;
|
||||
case STAT_QUERY_REST_SUBSID_REQ:
|
||||
g_rest_proxy_env.query_rest_subscrib_req_num++;
|
||||
break;
|
||||
case STAT_QUERY_REST_SUBSID_RES:
|
||||
g_rest_proxy_env.query_rest_subscrib_res_num++;
|
||||
break;
|
||||
case STAT_QUERY_REST_REQ:
|
||||
g_rest_proxy_env.query_rest_req_num++;
|
||||
break;
|
||||
case STAT_QUERY_REST_RES:
|
||||
g_rest_proxy_env.query_rest_res_num++;
|
||||
break;
|
||||
case STAT_TOPUP_REQ:
|
||||
g_rest_proxy_env.topup_req_num++;
|
||||
break;
|
||||
case STAT_TOPUP_RES:
|
||||
g_rest_proxy_env.topup_res_num++;
|
||||
break;
|
||||
case STAT_TOPUP_REST_SUBSID_REQ:
|
||||
g_rest_proxy_env.topup_rest_subscrib_req_num++;
|
||||
break;
|
||||
case STAT_TOPUP_REST_SUBSID_RES:
|
||||
g_rest_proxy_env.topup_rest_subscrib_res_num++;
|
||||
break;
|
||||
case STAT_TOPUP_REST_REQ:
|
||||
g_rest_proxy_env.topup_rest_req_num++;
|
||||
break;
|
||||
case STAT_TOPUP_REST_RES:
|
||||
g_rest_proxy_env.topup_rest_res_num++;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
9
proxy_c/rest_proxy_stat.h
Normal file
9
proxy_c/rest_proxy_stat.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef __REST_PROXY_STAT_H__
|
||||
#define __REST_PROXY_STAT_H__
|
||||
|
||||
#include "restapi.h"
|
||||
|
||||
void rest_proxy_stat_count(int stat_type);
|
||||
|
||||
|
||||
#endif /* __REST_PROXY_STAT_H__ */
|
||||
3365
proxy_c/restapi.c
Normal file
3365
proxy_c/restapi.c
Normal file
File diff suppressed because it is too large
Load Diff
687
proxy_c/restapi.h
Normal file
687
proxy_c/restapi.h
Normal file
@@ -0,0 +1,687 @@
|
||||
#ifndef _RESTAPI_H
|
||||
#define _RESTAPI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define MAX_BODY_LEN 1024
|
||||
|
||||
#define REST_PROXY_PORT 4951
|
||||
|
||||
enum RESULT_TYPE
|
||||
{
|
||||
RES_SUCCEED = 0,
|
||||
RES_FAILED,
|
||||
};
|
||||
|
||||
enum OCS_RESULT_TYPE
|
||||
{
|
||||
OCS_RES_SUCCEED = 2001,
|
||||
};
|
||||
|
||||
enum ERROR_CODE
|
||||
{
|
||||
ERR_UNKNOWN_SUBS = 1,
|
||||
ERR_WRONG_PWD,
|
||||
ERR_WRONG_CARD_STATUS,
|
||||
ERR_WRONG_CARD_EXPIRED,
|
||||
ERR_TIMEROUT,
|
||||
ERR_NO_PREFIX,
|
||||
};
|
||||
|
||||
enum REST_PROXY_MSG_TYPE
|
||||
{
|
||||
REST_QUERY=1,
|
||||
REST_TOPUP=2,
|
||||
REST_TRANSFER=3,
|
||||
|
||||
// for selfcare
|
||||
REST_SEND_AUTHCODE_REQ=5, // <20>û<EFBFBD>ע<EFBFBD><D7A2><EFBFBD><EFBFBD><EFBFBD>Žӿ<C5BD>
|
||||
REST_SEND_AUTHCODE_RSP=6,
|
||||
REST_QUERY_USERDATA_REQ=7, // <20>û<EFBFBD><C3BB><EFBFBD>Ϣ<EFBFBD><CFA2>ѯ<EFBFBD>ӿ<EFBFBD>
|
||||
REST_QUERY_USERDATA_RSP=8,
|
||||
REST_BUNDLE_SUBS_REQ=9, // <20>ײͶ<D7B2><CDB6><EFBFBD><EFBFBD>ӿ<EFBFBD>
|
||||
REST_BUNDLE_SUBS_RSP=10,
|
||||
REST_BUNDLE_USAGE_REQ=11, // <20>Ѷ<EFBFBD><D1B6><EFBFBD><EFBFBD>ײͲ<D7B2>ѯ
|
||||
REST_BUNDLE_USAGE_RSP=12,
|
||||
REST_RECHARGE_REQ=13, // <20><>ֵ<EFBFBD>ӿ<EFBFBD>
|
||||
REST_RECHARGE_RSP=14,
|
||||
REST_TRANSFER_REQ=15, // ת<>˽ӿ<CBBD>
|
||||
REST_TRANSFER_RSP=16,
|
||||
REST_RECHARGE_CARD_REQ=17, // <20><>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>ֵ<EFBFBD>ӿ<EFBFBD>
|
||||
REST_RECHARGE_CARD_RSP=18,
|
||||
REST_CHECK_BALANCE_REQ=19, // <20>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD>ӿ<EFBFBD>
|
||||
REST_CHECK_BALANCE_RSP=20,
|
||||
REST_QUERY_BALANCE_REQ=21, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ<EFBFBD>ӿ<EFBFBD>
|
||||
REST_QUERY_BALANCE_RSP=22,
|
||||
REST_QUERY_RECHARGE_CARD_REQ=23, // query recharge card interface from CRM
|
||||
REST_QUERY_RECHARGE_CARD_RSP=24,
|
||||
REST_UPDATE_RECHARGE_CARD_REQ=25, // update recharge card interface with CRM
|
||||
REST_UPDATE_RECHARGE_CARD_RSP=26,
|
||||
|
||||
REST_CRM_PAYMENT_REQ=27,
|
||||
REST_CRM_PAYMENT_RES=28,
|
||||
|
||||
REST_CRM_SMS_DELIVER_REQ=29,
|
||||
REST_CRM_SMS_DELIVER_RES=30,
|
||||
|
||||
REST_CRM_CREATE_ACCT_REQ=31,
|
||||
REST_CRM_CREATE_ACCT_RES=32,
|
||||
|
||||
REST_CRM_QUERY_TARIFF_REQ=33,
|
||||
REST_CRM_QUERY_TARIFF_RES=34,
|
||||
|
||||
REST_CRM_UPDATE_SUBS_REQ=35,
|
||||
REST_CRM_UPDATE_SUBS_RES=36,
|
||||
|
||||
REST_CRM_DELETE_SUBS_REQ=37,
|
||||
REST_CRM_DELETE_SUBS_RES=38,
|
||||
|
||||
REST_CRM_UPDATE_SESS_INFO_REQ=39,
|
||||
REST_CRM_UPDATE_SESS_INFO_RES=40,
|
||||
|
||||
REST_CRM_UPDATE_PLAN_INFO_REQ=41,
|
||||
REST_CRM_UPDATE_PLAN_INFO_RES=42,
|
||||
|
||||
REST_CRM_RENT_CHARGE=43,
|
||||
|
||||
|
||||
//
|
||||
};
|
||||
|
||||
#if 0
|
||||
enum PAY_TYPE
|
||||
{
|
||||
PAY_TYPE_BALANCE = 1,
|
||||
PAY_TYPE_PAYPAL = 2,
|
||||
PAY_TYPE_VISA = 3,
|
||||
PAY_TYPE_MASTER = 4,
|
||||
};
|
||||
|
||||
enum ACCT_STATUS
|
||||
{
|
||||
AS_FRESH, /* fresh account, can't dial in or out,
|
||||
but can recharge. */
|
||||
AS_NORMAL, /* normal account */
|
||||
AS_SUSPEND,
|
||||
AS_BLACKLIST,
|
||||
AS_RELEASED,
|
||||
AS_OPRTRIAL,
|
||||
//AS_MAX_USER_TYPE,
|
||||
|
||||
AS_EXTERNAL=10,
|
||||
};
|
||||
#endif
|
||||
|
||||
enum REST_IE_TAG
|
||||
{
|
||||
IE_SRC_REF=1,
|
||||
IE_DST_REF,
|
||||
IE_MSISDN,
|
||||
IE_RESULT,
|
||||
IE_ERROR_CODE,
|
||||
IE_BALANCE,
|
||||
IE_MO_EXPIRY,
|
||||
IE_MT_EXPIRY,
|
||||
IE_USERNAME,
|
||||
IE_PASSWORD,
|
||||
IE_MSG_CONTENT,//value=11
|
||||
IE_STATUS,
|
||||
IE_REMARK,
|
||||
IE_GROUP_NAME,
|
||||
IE_MO_VOICE_MIN,// in minute
|
||||
IE_REMAIN_MO_VOICE_SEC,// in second
|
||||
IE_REMAIN_MO_VOICE_MIN,// in minute
|
||||
IE_MT_VOICE_MIN,// in minute
|
||||
IE_REMAIN_MT_VOICE_SEC,// in second
|
||||
IE_REMAIN_MT_VOICE_MIN,// in minute
|
||||
IE_SMS_NUM, //value=21
|
||||
IE_REMAIN_SMS_NUM,
|
||||
IE_DATA_VOL_MB,// in MB
|
||||
IE_REMAIN_DATA_VOL_KB,// in KB
|
||||
IE_REMAIN_DATA_VOL_MB,// in MB
|
||||
IE_PAY_TYPE,
|
||||
IE_AMOUNT,
|
||||
IE_VALID_DAYS,
|
||||
IE_EXPIRY_TIME,
|
||||
IE_MSISDN_TRANS_OUT,
|
||||
IE_MSISDN_TRANS_IN, //value=31
|
||||
IE_BALANCE_AVAILABLE,
|
||||
IE_RECHARGE_AMOUNT,
|
||||
IE_RECHARGE_TYPE,
|
||||
IE_RECHARGE_CARD_STATUS,
|
||||
IE_RECHARGE_CARD_FACE_VALUE,
|
||||
IE_RECHARGE_CARD_EXPIRED_TS,
|
||||
IE_RECHARGE_CARD_UPDATED_TS,
|
||||
IE_CUSTOMER_ID,
|
||||
IE_ACCOUNT_ID,
|
||||
IE_PRODUCT_ID, //value=41
|
||||
IE_PLAN_ID,
|
||||
IE_RENT_CHARGE,
|
||||
IE_BIRTHDAY,
|
||||
IE_SMS_CONTENT,
|
||||
IE_SERVICE_TYPE,
|
||||
IE_TARIIFF_PREFIX,
|
||||
IE_TARIFF_UNIT,
|
||||
IE_TARIFF_CHARGE,
|
||||
IE_TARIFF_DISCOUNT,
|
||||
IE_PLAN_VALUE,//value=51
|
||||
IE_PLAN_USED_VALUE,
|
||||
IE_BUNDLE_ID,
|
||||
IE_CAUSE,
|
||||
IE_SESS_FLAG,
|
||||
IE_TIMESTAMP,
|
||||
IE_CONSUME_VALUE,
|
||||
IE_CALLED_NUMBER,
|
||||
IE_UE_IP,
|
||||
IE_GW_IP,
|
||||
IE_CUG_ID,
|
||||
IE_VAS_CUG_STATUS,
|
||||
IE_SESS_UPDATE_TIME,
|
||||
IE_PLAN_VALUE_ADD_THIS_TIME,
|
||||
IE_USER_CLASS,
|
||||
IE_MAX_NUM,
|
||||
};
|
||||
|
||||
typedef struct rest_header
|
||||
{
|
||||
u16 src_ref;
|
||||
u16 dst_ref;
|
||||
}_rest_header;
|
||||
|
||||
typedef struct rest_query
|
||||
{
|
||||
char msisdn[24];
|
||||
}_rest_query;
|
||||
|
||||
typedef struct rest_query_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result;
|
||||
u8 error_code;
|
||||
u32 balance;
|
||||
u32 mo_expiry;
|
||||
u32 mt_expiry;
|
||||
}_rest_query_res;
|
||||
|
||||
typedef struct rest_topup
|
||||
{
|
||||
u8 optional_flag; /* optional=1 ,account_id is presented */
|
||||
char msisdn[24];
|
||||
|
||||
char username[24];
|
||||
char password[24];
|
||||
u32 balance;
|
||||
long account_id;
|
||||
}_rest_topup;
|
||||
|
||||
|
||||
typedef struct rest_topup_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result;
|
||||
u8 error_code;
|
||||
u32 balance;
|
||||
u32 mo_expiry;
|
||||
u32 mt_expiry;
|
||||
}_rest_topup_res;
|
||||
|
||||
// for selfcare =============================
|
||||
typedef struct rest_send_authcode
|
||||
{
|
||||
char msisdn[24];
|
||||
char sms_content[MAX_BODY_LEN];
|
||||
}_rest_send_authcode;
|
||||
|
||||
typedef struct rest_send_authcode_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result;
|
||||
u32 error_code;
|
||||
}_rest_send_authcode_res;
|
||||
|
||||
typedef struct rest_query_user_data
|
||||
{
|
||||
char msisdn[24];
|
||||
}_rest_query_user_data;
|
||||
|
||||
typedef struct rest_query_user_data_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result;
|
||||
u32 error_code;
|
||||
|
||||
char msisdn[24];
|
||||
u8 status;// use ACCT_STATUS
|
||||
char remark[64];
|
||||
char usrGrpName[32];// usr data==>cos id==>cos title
|
||||
u32 balance;
|
||||
u64 mo_expiry;
|
||||
u32 mo_voc_min;// in Min
|
||||
u32 remain_mo_voc_min;
|
||||
u32 mt_voc_min;// in Min
|
||||
u32 remain_mt_voc_min;
|
||||
u32 total_sms_num;// reserved, set to 0 or do not send
|
||||
u32 remain_sms_num;
|
||||
u32 total_data_vol;// reserved, set to 0 or do not send
|
||||
u32 remain_data_vol;
|
||||
}_rest_query_user_data_res;
|
||||
|
||||
typedef struct rest_bundle_subs
|
||||
{
|
||||
char msisdn[24];
|
||||
u8 payType;// 1: balance; 2: paypal; 3: visa; 4: master, use PAY_TYPE
|
||||
u32 charge;// Conditional, mandatory if balance
|
||||
u32 moVoiceMinute;
|
||||
u32 mtVoiceMinute;
|
||||
u32 dataVolume;// MB
|
||||
u32 smsNum;
|
||||
u32 validDays;
|
||||
}_rest_bundle_subs;
|
||||
|
||||
|
||||
typedef struct rest_bundle_subs_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result;
|
||||
u32 error_code;
|
||||
}_rest_bundle_subs_res;
|
||||
|
||||
|
||||
typedef struct rest_bundle_usage
|
||||
{
|
||||
char msisdn[24];
|
||||
}_rest_bundle_usage;
|
||||
|
||||
|
||||
typedef struct rest_bundle_usage_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result;
|
||||
u32 error_code;
|
||||
u32 moVoiceInSec;// remained mo voice in second
|
||||
u32 mtVoiceInSec;// remained mt voice in second
|
||||
u32 dataVolInKB;// remained data volume in KB
|
||||
u32 smsNum;// remained sms
|
||||
u64 expiredTime;// expired time
|
||||
}_rest_bundle_usage_res;
|
||||
|
||||
|
||||
typedef struct rest_recharge
|
||||
{
|
||||
char msisdn[24];
|
||||
|
||||
u32 amount;// mandatory, add to balance
|
||||
u8 op_type; //0=charge, 1=recharge
|
||||
u16 valid_days;
|
||||
}_rest_recharge;
|
||||
|
||||
|
||||
typedef struct rest_recharge_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result;
|
||||
u32 error_code;
|
||||
u8 status;
|
||||
u32 balance;// current balance
|
||||
u64 expiredTime;// expired time
|
||||
}_rest_recharge_res;
|
||||
|
||||
|
||||
typedef struct rest_transfer
|
||||
{
|
||||
char transferOutMsisdn[24];
|
||||
char transferInMsisdn[24];
|
||||
|
||||
u32 amount;// mandatory
|
||||
}_rest_transfer;
|
||||
|
||||
|
||||
typedef struct rest_transfer_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result;
|
||||
u32 error_code;
|
||||
u32 balance;
|
||||
}_rest_transfer_res;
|
||||
|
||||
|
||||
typedef struct rest_recharge_card
|
||||
{
|
||||
char msisdn[24];
|
||||
|
||||
char cardPwd[32];// rechare card password
|
||||
}_rest_recharge_card;
|
||||
|
||||
|
||||
typedef struct rest_recharge_card_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result;
|
||||
u32 error_code;
|
||||
u32 rechargeAmount;// mandatory, add to balance
|
||||
u32 balance;// current balance
|
||||
u64 expiredTime;// expired time
|
||||
}_rest_recharge_card_res;
|
||||
|
||||
|
||||
typedef struct rest_check_balance
|
||||
{
|
||||
char msisdn[24];
|
||||
|
||||
u32 amount;// mandatory
|
||||
}_rest_check_balance;
|
||||
|
||||
|
||||
typedef struct rest_check_balance_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result;
|
||||
u32 error_code;
|
||||
u8 available;// 0: enough balance; 1: else
|
||||
}_rest_check_balance_res;
|
||||
|
||||
|
||||
typedef struct rest_query_balance
|
||||
{
|
||||
char msisdn[24];
|
||||
}_rest_query_balance;
|
||||
|
||||
|
||||
typedef struct rest_query_balance_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result;
|
||||
u32 error_code;
|
||||
u8 status;
|
||||
u32 balance;// current balance
|
||||
u32 mo_expiry;
|
||||
}_rest_query_balance_res;
|
||||
|
||||
typedef struct rest_query_recharge_card
|
||||
{
|
||||
char cardPwd[32];// rechare card password
|
||||
}_rest_query_recharge_card;
|
||||
|
||||
|
||||
typedef struct rest_query_recharge_card_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result; //0=succeed, 1=failed
|
||||
u32 error_code;//1=no such instance
|
||||
u32 status;//0=fresh, 1= used
|
||||
u32 face_value;
|
||||
u32 expiredTime;// expired time
|
||||
}_rest_query_recharge_card_res;
|
||||
|
||||
typedef struct rest_update_recharge_card
|
||||
{
|
||||
char cardPwd[32];// rechare card password
|
||||
u8 status;
|
||||
u64 updatedTime;
|
||||
char msisdn[32];
|
||||
}_rest_update_recharge_card;
|
||||
|
||||
|
||||
typedef struct rest_update_recharge_card_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result;
|
||||
u32 error_code;
|
||||
}_rest_update_recharge_card_res;
|
||||
|
||||
typedef struct rest_payment
|
||||
{
|
||||
char msisdn[24];
|
||||
|
||||
u32 amount;// mandatory, add to balance
|
||||
}_rest_payment;
|
||||
|
||||
|
||||
typedef struct rest_payment_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result;
|
||||
u32 error_code;
|
||||
u32 balance;// current balance
|
||||
u64 expiredTime;// expired time
|
||||
}_rest_payment_res;
|
||||
|
||||
typedef struct rest_sms_deliver_req
|
||||
{
|
||||
char msisdn[24];
|
||||
u16 sms_len;
|
||||
char sms_content[MAX_BODY_LEN];
|
||||
}_rest_sms_deliver_req;
|
||||
|
||||
typedef struct rest_sms_deliver_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result;
|
||||
u32 error_code;
|
||||
}_rest_sms_deliver_res;
|
||||
|
||||
typedef struct rest_create_acct_req
|
||||
{
|
||||
char msisdn[24];
|
||||
u32 customer_id;
|
||||
u32 account_id;
|
||||
u32 product_id;
|
||||
u32 plan_id; /* basic plan */
|
||||
u8 user_class;
|
||||
u32 balance;
|
||||
u32 expiry_date;
|
||||
u32 rent_charge;
|
||||
u32 birthday;
|
||||
u32 cug_id;
|
||||
}_rest_create_acct_req;
|
||||
|
||||
typedef struct rest_create_acct_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result;
|
||||
u32 error_code;
|
||||
}_rest_create_acct_res;
|
||||
|
||||
typedef struct rest_query_tariff_req
|
||||
{
|
||||
char msisdn[24];
|
||||
u8 service_type; /*0=mo call, 1=mt call, 2=sms, 3=data */
|
||||
char called_number[24];
|
||||
}_rest_query_tariff_req;
|
||||
|
||||
typedef struct rest_query_tariff_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result;
|
||||
u32 error_code;
|
||||
char prefix[24];
|
||||
u32 unit_time;
|
||||
u32 unit_charge;
|
||||
u32 discount;
|
||||
u32 plan_id;
|
||||
u32 bundle_plan_id;
|
||||
u64 total_plan_value;
|
||||
u64 used_plan_value;
|
||||
}_rest_query_tariff_res;
|
||||
|
||||
typedef struct rest_update_subs_req
|
||||
{
|
||||
u32 optional_flag;
|
||||
char msisdn[24];
|
||||
u32 account_id;
|
||||
u8 status; /*falg=1*/
|
||||
u32 balance;
|
||||
u32 balance_expiry_date;
|
||||
u32 basic_plan_id;
|
||||
u32 basic_plan_rent;
|
||||
u8 vas_cug_status;
|
||||
}_rest_update_subs_req;
|
||||
|
||||
typedef struct rest_update_subs_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result;
|
||||
u32 error_code;
|
||||
}_rest_update_subs_res;
|
||||
|
||||
typedef struct rest_delete_subs_req
|
||||
{
|
||||
char msisdn[24];
|
||||
u8 account_type;
|
||||
u32 account_id;
|
||||
u8 cause;
|
||||
}_rest_delete_subs_req;
|
||||
|
||||
typedef struct rest_delete_subs_res
|
||||
{
|
||||
u8 optional_flag;
|
||||
u8 result;
|
||||
u32 error_code;
|
||||
}_rest_delete_subs_res;
|
||||
|
||||
typedef struct rest_update_sess_info_req
|
||||
{
|
||||
u32 optional_flag; /*bit 0=called, 1= ue_ip, 2=pgw ip */
|
||||
char msisdn[24];
|
||||
u8 first_sess; /*if 1 then clear all session in database */
|
||||
u8 service_type; /*0=mo call, 1=mt call, 2=mo sms, 3= data*/
|
||||
u32 start_time;
|
||||
u32 consumed_value; /*duration of call, bytes of data */
|
||||
char called[24]; /*for call/sms */
|
||||
u32 ue_ip;
|
||||
u32 gw_ip;
|
||||
}_rest_update_sess_info_req;
|
||||
|
||||
|
||||
typedef struct rest_update_plan_info_req
|
||||
{
|
||||
u32 optional_flag; /*bit 0=called, 1= ue_ip, 2=pgw ip */
|
||||
char msisdn[24];
|
||||
u8 service_type; /*0=mo call, 1=mt call, 2=mo sms, 3= data*/
|
||||
u32 account_id;
|
||||
u32 plan_id;
|
||||
u32 bundle_id;
|
||||
u64 plan_total_value;
|
||||
u64 plan_used_value;
|
||||
u32 sess_update_times;
|
||||
u64 this_time_add_value;
|
||||
}_rest_update_plan_info_req;
|
||||
|
||||
typedef struct rest_rent_charge_req
|
||||
{
|
||||
u32 optional_flag;
|
||||
char msisdn[24];
|
||||
u32 balance;
|
||||
u32 rent_charge;
|
||||
}_rest_rent_charge_req;
|
||||
|
||||
//======================================
|
||||
|
||||
typedef struct rest_msg_s
|
||||
{
|
||||
u8 msg_type;
|
||||
_rest_header header;
|
||||
union
|
||||
{
|
||||
//OCS->CRM
|
||||
_rest_query query;
|
||||
_rest_query_res query_res;
|
||||
_rest_topup topup;
|
||||
_rest_topup_res topup_res;
|
||||
|
||||
// for selfcare
|
||||
_rest_send_authcode send_authcode;
|
||||
_rest_send_authcode_res send_authcode_res;
|
||||
_rest_query_user_data query_user_data;
|
||||
_rest_query_user_data_res query_user_data_res;
|
||||
_rest_bundle_subs bundle_subs;
|
||||
_rest_bundle_subs_res bundle_subs_res;
|
||||
_rest_bundle_usage bundle_usage;
|
||||
_rest_bundle_usage_res bundle_usage_res;
|
||||
_rest_recharge recharge;
|
||||
_rest_recharge_res recharge_res;
|
||||
_rest_transfer transfer;
|
||||
_rest_transfer_res transfer_res;
|
||||
_rest_recharge_card recharge_card;
|
||||
_rest_recharge_card_res recharge_card_res;
|
||||
_rest_check_balance check_balance;
|
||||
_rest_check_balance_res check_balance_res;
|
||||
_rest_query_balance query_balance;
|
||||
_rest_query_balance_res query_balance_res;
|
||||
_rest_query_recharge_card query_recharge_card;
|
||||
_rest_query_recharge_card_res query_recharge_card_res;
|
||||
_rest_update_recharge_card update_recharge_card;
|
||||
_rest_update_recharge_card_res update_recharge_card_res;
|
||||
|
||||
_rest_payment payment;
|
||||
_rest_payment_res payment_res;
|
||||
|
||||
_rest_sms_deliver_req sms_deliver;
|
||||
_rest_sms_deliver_res sms_deliver_res;
|
||||
|
||||
_rest_create_acct_req create_acct;
|
||||
_rest_create_acct_res create_acct_res;
|
||||
|
||||
_rest_query_tariff_req query_tariff;
|
||||
_rest_query_tariff_res query_tariff_res;
|
||||
|
||||
_rest_update_subs_req update_subs;
|
||||
_rest_update_subs_res update_subs_res;
|
||||
|
||||
_rest_delete_subs_req delete_subs;
|
||||
_rest_delete_subs_res delete_subs_res;
|
||||
|
||||
_rest_update_sess_info_req update_sess_info;
|
||||
|
||||
_rest_update_plan_info_req update_plan_info;
|
||||
|
||||
_rest_rent_charge_req rent_charge;
|
||||
|
||||
//
|
||||
}msg;
|
||||
}_rest_msg_s;
|
||||
|
||||
int encode_rest_query(_rest_msg_s *ptr, u8 *buf);
|
||||
|
||||
int encode_rest_query_res(_rest_msg_s *ptr, u8 *buf);
|
||||
|
||||
int encode_rest_topup(_rest_msg_s *ptr, u8 *buf);
|
||||
|
||||
int encode_rest_topup_res(_rest_msg_s *ptr, u8 *buf);
|
||||
|
||||
int decode_rest_api_msg(u8 *buf, int len, _rest_msg_s *ptr);
|
||||
|
||||
// for selfcare======================================
|
||||
int encode_rest(_rest_msg_s *ptr, u8 *buf);
|
||||
int decode_rest_api_msg(u8 *buf, int len, _rest_msg_s *ptr);
|
||||
|
||||
int encode_rest_send_authcode(_rest_msg_s *ptr, u8 *buf);
|
||||
int encode_rest_send_authcode_res(_rest_msg_s *ptr, u8 *buf);
|
||||
int encode_rest_query_user_data(_rest_msg_s *ptr, u8 *buf);
|
||||
int encode_rest_query_user_data_res(_rest_msg_s *ptr, u8 *buf);
|
||||
int encode_rest_bundle_subs(_rest_msg_s *ptr, u8 *buf);
|
||||
int encode_rest_bundle_subs_res(_rest_msg_s *ptr, u8 *buf);
|
||||
int encode_rest_bundle_usage(_rest_msg_s *ptr, u8 *buf);
|
||||
int encode_rest_bundle_usage_res(_rest_msg_s *ptr, u8 *buf);
|
||||
int encode_rest_recharge(_rest_msg_s *ptr, u8 *buf);
|
||||
int encode_rest_recharge_res(_rest_msg_s *ptr, u8 *buf);
|
||||
int encode_rest_transfer(_rest_msg_s *ptr, u8 *buf);
|
||||
int encode_rest_transfer_res(_rest_msg_s *ptr, u8 *buf);
|
||||
int encode_rest_recharge_card(_rest_msg_s *ptr, u8 *buf);
|
||||
int encode_rest_recharge_card_res(_rest_msg_s *ptr, u8 *buf);
|
||||
int encode_rest_check_balance(_rest_msg_s *ptr, u8 *buf);
|
||||
int encode_rest_check_balance_res(_rest_msg_s *ptr, u8 *buf);
|
||||
int encode_rest_query_balance(_rest_msg_s *ptr, u8 *buf);
|
||||
int encode_rest_query_balance_res(_rest_msg_s *ptr, u8 *buf);
|
||||
//
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
229
proxy_c/selfcare_config.c
Normal file
229
proxy_c/selfcare_config.c
Normal file
@@ -0,0 +1,229 @@
|
||||
#include "selfcare_config.h"
|
||||
#include "common.h"
|
||||
#include "log.h"
|
||||
|
||||
|
||||
#define SELFCARE_PROXY_DEFAULT_CONF_FILE "./conf/selfcare_proxy.conf"
|
||||
|
||||
#define MAX_ERRCODE (5000)
|
||||
#define MAX_MESSAGE_LEN (100)
|
||||
static char g_errcode_map_message[MAX_ERRCODE][MAX_MESSAGE_LEN];
|
||||
|
||||
|
||||
static selfcare_config_s g_selfcare_conf;
|
||||
|
||||
void _selfcare_config_str(const char* buffer, const char* key, char* val)
|
||||
{
|
||||
char *pos = NULL;
|
||||
char *pos_val_start = NULL;
|
||||
/* first address is start of the line */
|
||||
pos = strstr(buffer, key);
|
||||
if(NULL != pos && buffer == pos)
|
||||
{
|
||||
pos_val_start = strstr(pos, "=");
|
||||
|
||||
/* remove \r or \n which first appear */
|
||||
pos = pos_val_start;
|
||||
while(pos)
|
||||
{
|
||||
if(*pos == '\r' || *pos == '\n' || *pos == '\0')
|
||||
break;
|
||||
pos++;
|
||||
}
|
||||
if(pos)
|
||||
*pos = '\0';
|
||||
|
||||
if(NULL != pos_val_start)
|
||||
{
|
||||
strcpy(val, pos_val_start + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _selfcare_config_i16(const char* buffer, const char* key, short unsigned int* val)
|
||||
{
|
||||
char *pos = NULL;
|
||||
char *pos_val_start = NULL;
|
||||
/* first address is start of the line */
|
||||
pos = strstr(buffer, key);
|
||||
if(NULL != pos && buffer == pos)
|
||||
{
|
||||
pos_val_start = strstr(pos, "=");
|
||||
|
||||
/* remove \r or \n which first appear */
|
||||
pos = pos_val_start;
|
||||
while(pos)
|
||||
{
|
||||
if(*pos == '\r' || *pos == '\n' || *pos == '\0')
|
||||
break;
|
||||
pos++;
|
||||
}
|
||||
if(pos)
|
||||
*pos = '\0';
|
||||
|
||||
if(NULL != pos_val_start)
|
||||
{
|
||||
*val = atoi( pos_val_start + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _selfcare_config_i32(const char* buffer, const char* key, unsigned int* val)
|
||||
{
|
||||
char *pos = NULL;
|
||||
char *pos_val_start = NULL;
|
||||
/* first address is start of the line */
|
||||
pos = strstr(buffer, key);
|
||||
if(NULL != pos && buffer == pos)
|
||||
{
|
||||
pos_val_start = strstr(pos, "=");
|
||||
|
||||
/* remove \r or \n which first appear */
|
||||
pos = pos_val_start;
|
||||
while(pos)
|
||||
{
|
||||
if(*pos == '\r' || *pos == '\n' || *pos == '\0')
|
||||
break;
|
||||
pos++;
|
||||
}
|
||||
if(pos)
|
||||
*pos = '\0';
|
||||
|
||||
if(NULL != pos_val_start)
|
||||
{
|
||||
*val = atoi( pos_val_start + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void _selfcare_config_ipport(const char* buffer,
|
||||
const char* key,
|
||||
unsigned int* ip,
|
||||
char* ip_str,
|
||||
unsigned short* port)
|
||||
{
|
||||
char buffer_ip[16] = {0};
|
||||
// char buffer_port[4] = {0};
|
||||
char *pos = NULL;
|
||||
char *pos_ip_start = NULL;
|
||||
char *pos_ip_end = NULL;
|
||||
/* first address is start of the line */
|
||||
pos = strstr(buffer, key);
|
||||
if(NULL != pos && buffer == pos)
|
||||
{
|
||||
pos_ip_start = strstr(pos, "=");
|
||||
if(NULL != pos_ip_start)
|
||||
{
|
||||
pos_ip_end = strstr(pos_ip_start + 1, ":");
|
||||
if(NULL != pos_ip_end)
|
||||
{
|
||||
memcpy(buffer_ip, pos_ip_start + 1, (pos_ip_end - 1) - (pos_ip_start + 1) + 1);
|
||||
if(ip_str)
|
||||
{
|
||||
strcpy(ip_str, buffer_ip);
|
||||
}
|
||||
*ip = inet_addr(buffer_ip);
|
||||
*port = atoi(pos_ip_end + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void _selfcare_config_errcodemapmsg(const char* buffer)
|
||||
{
|
||||
char buf_map[MAX_MESSAGE_LEN] = {0};
|
||||
|
||||
_selfcare_config_str(buffer, "errcode_map_message", buf_map);
|
||||
if(buf_map[0] != '\0')
|
||||
{
|
||||
char *p_1 = strstr(buf_map, "[");
|
||||
char *p_2 = strstr(buf_map, ",");
|
||||
char *p_3 = strstr(buf_map, "]");
|
||||
if(p_1 && p_2 && p_3)
|
||||
{
|
||||
char errcode_str[MAX_MESSAGE_LEN] = {0};
|
||||
memcpy(errcode_str, p_1 + 1, p_2 - (p_1 + 1) );
|
||||
|
||||
char errmsg_str[MAX_MESSAGE_LEN] = {0};
|
||||
memcpy(errmsg_str, p_2 + 1, p_3 - (p_2 + 1) );
|
||||
|
||||
int err_code = atoi(errcode_str);
|
||||
strcpy(g_errcode_map_message[err_code%MAX_ERRCODE], errmsg_str);
|
||||
|
||||
LOG_D("[rest_proxy] load errorcodemap. [%d,%s]\n", err_code, errmsg_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char *rest_proxy_errcodemsg(const unsigned int errcode)
|
||||
{
|
||||
if(g_errcode_map_message[errcode%MAX_ERRCODE][0] == '\0')
|
||||
{
|
||||
return "unkow";
|
||||
}
|
||||
|
||||
return g_errcode_map_message[errcode%MAX_ERRCODE];
|
||||
}
|
||||
|
||||
int selfcare_config_init(const char *cnf_file)
|
||||
{
|
||||
#define BUFFER_LEN 1024
|
||||
FILE* fd;
|
||||
char buffer[BUFFER_LEN] = {0};
|
||||
|
||||
if(cnf_file == NULL)
|
||||
{
|
||||
g_selfcare_conf.cnf_file = SELFCARE_PROXY_DEFAULT_CONF_FILE;
|
||||
}
|
||||
|
||||
/* Create input file descriptor */
|
||||
fd = fopen (g_selfcare_conf.cnf_file, "r");
|
||||
if (fd == NULL)
|
||||
{
|
||||
perror ("open");
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Copy process */
|
||||
while((fgets(buffer, BUFFER_LEN, fd)) != NULL)
|
||||
{
|
||||
if(buffer[0] == '#')
|
||||
continue;
|
||||
_selfcare_config_ipport(buffer, "udp_localIPPort", &g_selfcare_conf.udp_local_ip, NULL, &g_selfcare_conf.udp_local_port);
|
||||
_selfcare_config_ipport(buffer, "udp_ocsIPPort", &g_selfcare_conf.udp_ocs_ip, NULL, &g_selfcare_conf.udp_ocs_port);
|
||||
_selfcare_config_i16(buffer, "http_localPort", &g_selfcare_conf.http_local_port);
|
||||
_selfcare_config_i32(buffer, "sms_notify_usage_75", &g_selfcare_conf.sms_notify_type);
|
||||
_selfcare_config_str(buffer, "authcode_url", g_selfcare_conf.authcode_url);
|
||||
_selfcare_config_str(buffer, "query_userdata_url", g_selfcare_conf.query_userdata_url);
|
||||
_selfcare_config_str(buffer, "bundle_subs_url", g_selfcare_conf.bundle_subs_url);
|
||||
_selfcare_config_str(buffer, "bundle_usage_url", g_selfcare_conf.bundle_usage_url);
|
||||
_selfcare_config_str(buffer, "recharge_url", g_selfcare_conf.recharge_url);
|
||||
_selfcare_config_str(buffer, "transfer_url", g_selfcare_conf.transfer_url);
|
||||
_selfcare_config_str(buffer, "recharge_card_url", g_selfcare_conf.recharge_card_url);
|
||||
_selfcare_config_str(buffer, "check_balance_url", g_selfcare_conf.check_balance_url);
|
||||
_selfcare_config_str(buffer, "query_balane_url", g_selfcare_conf.query_balane_url);
|
||||
_selfcare_config_str(buffer, "payment_url", g_selfcare_conf.payment_url);
|
||||
_selfcare_config_str(buffer, "sms_deliver_url", g_selfcare_conf.sms_deliver_url);
|
||||
_selfcare_config_str(buffer, "create_account_url", g_selfcare_conf.create_account_url);
|
||||
_selfcare_config_str(buffer, "update_subs_url", g_selfcare_conf.update_subs_url);
|
||||
_selfcare_config_str(buffer, "delete_subs_url", g_selfcare_conf.delete_subs_url);
|
||||
|
||||
|
||||
_selfcare_config_errcodemapmsg(buffer);
|
||||
|
||||
memset(buffer, 0x00, BUFFER_LEN);
|
||||
}
|
||||
|
||||
fclose (fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int selfcare_config_uninit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
selfcare_config_s* selfcare_config_get(void)
|
||||
{
|
||||
return &g_selfcare_conf;
|
||||
}
|
||||
|
||||
54
proxy_c/selfcare_config.h
Normal file
54
proxy_c/selfcare_config.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef __SELFCARE_CONFIG_H__
|
||||
#define __SELFCARE_CONFIG_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct _selfcare_config_s
|
||||
{
|
||||
const char *cnf_file;
|
||||
|
||||
unsigned int udp_local_ip;
|
||||
unsigned short int udp_local_port;
|
||||
|
||||
unsigned int udp_ocs_ip;
|
||||
unsigned short int udp_ocs_port;
|
||||
|
||||
unsigned int http_local_ip;
|
||||
unsigned short int http_local_port;
|
||||
|
||||
unsigned int sms_notify_type;
|
||||
|
||||
char authcode_url[128];
|
||||
char query_userdata_url[128];
|
||||
char bundle_subs_url[128];
|
||||
char bundle_usage_url[128];
|
||||
char recharge_url[128];
|
||||
char transfer_url[128];
|
||||
char recharge_card_url[128];
|
||||
char check_balance_url[128];
|
||||
char query_balane_url[128];
|
||||
char payment_url[128];
|
||||
char sms_deliver_url[128];
|
||||
char create_account_url[128];
|
||||
char update_subs_url[128];
|
||||
char delete_subs_url[128];
|
||||
|
||||
|
||||
}selfcare_config_s;
|
||||
|
||||
|
||||
int selfcare_config_init(const char *cnf_file);
|
||||
|
||||
int selfcare_config_uninit(void);
|
||||
|
||||
selfcare_config_s* selfcare_config_get(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SELFCARE_CONFIG_H__ */
|
||||
852
proxy_c/selfcare_endecode.c
Normal file
852
proxy_c/selfcare_endecode.c
Normal file
@@ -0,0 +1,852 @@
|
||||
#include "selfcare_endecode.h"
|
||||
#include "selfcare_httpsrv.h"
|
||||
#include "json.h"
|
||||
#include "restapi.h"
|
||||
#include "log.h"
|
||||
|
||||
extern ulong TransStrTimeToSecond(const char *str_time);//YYYY-MM-DD HH:MM:YY
|
||||
extern int dba_crm_get_product_rent(int from, int package_id);
|
||||
char* _find_name(json_t *node, const char* name)
|
||||
{
|
||||
if(node == NULL || node->type != JSON_STRING)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(strcmp(node->text, name) == 0)
|
||||
{
|
||||
if(node->child)
|
||||
{
|
||||
LOG_D("[httpserv] name[%s] val[%s]\n", name, node->child->text);
|
||||
return node->child->text;
|
||||
}
|
||||
}
|
||||
|
||||
return _find_name(node->next, name);
|
||||
}
|
||||
|
||||
int _selfcare_set_str(json_t *root, char *buf, const char *name)
|
||||
{
|
||||
int ret = 0;
|
||||
char *val = _find_name(root->child, name);
|
||||
|
||||
if(val)
|
||||
{
|
||||
strcpy(buf, val);
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
void _selfcare_set_u8(json_t *root, u8 *val, const char *name)
|
||||
{
|
||||
char *tmp = _find_name(root->child, name);
|
||||
if(tmp)
|
||||
{
|
||||
*val = atoi(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
void _selfcare_set_u16(json_t *root, u16 *val, const char *name)
|
||||
{
|
||||
char *tmp = _find_name(root->child, name);
|
||||
if(tmp)
|
||||
{
|
||||
*val = atoi(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
int _selfcare_set_u32(json_t *root, u32 *val, const char *name)
|
||||
{
|
||||
char *tmp = _find_name(root->child, name);
|
||||
if(tmp)
|
||||
{
|
||||
*val = atol(tmp);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void _print_name(json_t *node, const char* name)
|
||||
{
|
||||
char *val = _find_name(node->child, name);
|
||||
if(val != NULL)
|
||||
{
|
||||
LOG_D("[httpserv] name[%s] val[%s]\n", name, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("[httpserv] name[%s] not found\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
static int _selfcare_decode_authcode(const char *buff, const int len, _rest_msg_s *msg)
|
||||
{
|
||||
msg->msg_type = REST_SEND_AUTHCODE_REQ;
|
||||
|
||||
json_t *root = NULL;
|
||||
if(json_parse_document(&root, buff) == JSON_OK)
|
||||
{
|
||||
if(root != NULL && root->type == JSON_OBJECT)
|
||||
{
|
||||
LOG_D("\n");
|
||||
_selfcare_set_str(root, msg->msg.send_authcode.msisdn, "telNumber");
|
||||
_selfcare_set_str(root, msg->msg.send_authcode.sms_content, "content");
|
||||
}
|
||||
LOG_D("[httpserv] decode autchcode suc\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("[httpserv] decode autchcode fail\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int _selfcare_decode_query_user_data(const char *buff, const int len, _rest_msg_s *msg)
|
||||
{
|
||||
msg->msg_type = REST_QUERY_USERDATA_REQ;
|
||||
|
||||
json_t *root = NULL;
|
||||
if(json_parse_document(&root, buff) == JSON_OK)
|
||||
{
|
||||
if(root != NULL && root->type == JSON_OBJECT)
|
||||
{
|
||||
LOG_D("\n");
|
||||
_selfcare_set_str(root, msg->msg.query_user_data.msisdn, "telNumber");
|
||||
}
|
||||
LOG_D("[httpserv] decode query_user_data suc\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("[httpserv] decode query_user_data fail\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int _selfcare_decode_bundle_subs(const char *buff, const int len, _rest_msg_s *msg)
|
||||
{
|
||||
msg->msg_type = REST_BUNDLE_SUBS_REQ;
|
||||
|
||||
json_t *root = NULL;
|
||||
if(json_parse_document(&root, buff) == JSON_OK)
|
||||
{
|
||||
if(root != NULL && root->type == JSON_OBJECT)
|
||||
{
|
||||
LOG_D("\n");
|
||||
_selfcare_set_str(root, msg->msg.bundle_subs.msisdn, "telNumber");
|
||||
_selfcare_set_u8(root, &msg->msg.bundle_subs.payType, "payType");
|
||||
_selfcare_set_u32(root, &msg->msg.bundle_subs.charge, "chargedAmount");
|
||||
_selfcare_set_u32(root, &msg->msg.bundle_subs.moVoiceMinute, "moVoiceMinute");
|
||||
_selfcare_set_u32(root, &msg->msg.bundle_subs.mtVoiceMinute, "mtVoiceMinute");
|
||||
_selfcare_set_u32(root, &msg->msg.bundle_subs.dataVolume, "dataVolume");
|
||||
_selfcare_set_u32(root, &msg->msg.bundle_subs.smsNum, "smsVolume");
|
||||
_selfcare_set_u32(root, &msg->msg.bundle_subs.validDays, "validPeriod");
|
||||
}
|
||||
LOG_D("[httpserv] decode bundle_subs suc\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("[httpserv] decode bundle_subs fail\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int _selfcare_decode_bundle_usage(const char *buff, const int len, _rest_msg_s *msg)
|
||||
{
|
||||
msg->msg_type = REST_BUNDLE_USAGE_REQ;
|
||||
|
||||
json_t *root = NULL;
|
||||
if(json_parse_document(&root, buff) == JSON_OK)
|
||||
{
|
||||
if(root != NULL && root->type == JSON_OBJECT)
|
||||
{
|
||||
LOG_D("\n");
|
||||
_selfcare_set_str(root, msg->msg.bundle_usage.msisdn, "telNumber");
|
||||
}
|
||||
LOG_D("[httpserv] decode bundle_usage suc\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("[httpserv] decode bundle_usage fail\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int _selfcare_decode_recharge(const char *buff, const int len, _rest_msg_s *msg)
|
||||
{
|
||||
msg->msg_type = REST_RECHARGE_REQ;
|
||||
|
||||
json_t *root = NULL;
|
||||
if(json_parse_document(&root, buff) == JSON_OK)
|
||||
{
|
||||
if(root != NULL && root->type == JSON_OBJECT)
|
||||
{
|
||||
LOG_D("\n");
|
||||
_selfcare_set_str(root, msg->msg.recharge.msisdn, "telNumber");
|
||||
_selfcare_set_u32(root, &msg->msg.recharge.amount, "amount");
|
||||
_selfcare_set_u8(root, &msg->msg.recharge.op_type, "opType");
|
||||
_selfcare_set_u16(root, &msg->msg.recharge.valid_days, "validyDays");
|
||||
if(msg->msg.recharge.op_type == 1) //recharge with cash
|
||||
{
|
||||
//if(msg->msg.recharge.valid_days<=1)
|
||||
// msg->msg.recharge.valid_days = 7;
|
||||
}
|
||||
|
||||
}
|
||||
LOG_D("[httpserv] decode recharge suc\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("[httpserv] decode recharge fail\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int _selfcare_decode_transfer(const char *buff, const int len, _rest_msg_s *msg)
|
||||
{
|
||||
msg->msg_type = REST_TRANSFER_REQ;
|
||||
|
||||
json_t *root = NULL;
|
||||
if(json_parse_document(&root, buff) == JSON_OK)
|
||||
{
|
||||
if(root != NULL && root->type == JSON_OBJECT)
|
||||
{
|
||||
LOG_D("\n");
|
||||
_selfcare_set_str(root, msg->msg.transfer.transferOutMsisdn, "transferOut");
|
||||
_selfcare_set_str(root, msg->msg.transfer.transferInMsisdn, "transferIn");
|
||||
_selfcare_set_u32(root, &msg->msg.transfer.amount, "amount");
|
||||
}
|
||||
LOG_D("[httpserv] decode transfer suc\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("[httpserv] decode transfer fail\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int _selfcare_decode_recharge_card(const char *buff, const int len, _rest_msg_s *msg)
|
||||
{
|
||||
msg->msg_type = REST_RECHARGE_CARD_REQ;
|
||||
|
||||
json_t *root = NULL;
|
||||
if(json_parse_document(&root, buff) == JSON_OK)
|
||||
{
|
||||
if(root != NULL && root->type == JSON_OBJECT)
|
||||
{
|
||||
LOG_D("\n");
|
||||
_selfcare_set_str(root, msg->msg.recharge_card.msisdn, "telNumber");
|
||||
_selfcare_set_str(root, msg->msg.recharge_card.cardPwd, "cardPwd");
|
||||
//_selfcare_set_u32(root, &msg->msg.recharge_card.amount, "rechargeAmount");
|
||||
}
|
||||
LOG_D("[httpserv] decode recharge_card suc\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("[httpserv] decode recharge_card fail\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int _selfcare_decode_check_balance(const char *buff, const int len, _rest_msg_s *msg)
|
||||
{
|
||||
msg->msg_type = REST_CHECK_BALANCE_REQ;
|
||||
|
||||
json_t *root = NULL;
|
||||
if(json_parse_document(&root, buff) == JSON_OK)
|
||||
{
|
||||
if(root != NULL && root->type == JSON_OBJECT)
|
||||
{
|
||||
LOG_D("\n");
|
||||
_selfcare_set_str(root, msg->msg.check_balance.msisdn, "telNumber");
|
||||
_selfcare_set_u32(root, &msg->msg.check_balance.amount, "amount");
|
||||
}
|
||||
LOG_D("[httpserv] decode check_balance suc\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("[httpserv] decode check_balance fail\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int _selfcare_decode_query_balance(const char *buff, const int len, _rest_msg_s *msg)
|
||||
{
|
||||
msg->msg_type = REST_QUERY_BALANCE_REQ;
|
||||
|
||||
json_t *root = NULL;
|
||||
if(json_parse_document(&root, buff) == JSON_OK)
|
||||
{
|
||||
if(root != NULL && root->type == JSON_OBJECT)
|
||||
{
|
||||
LOG_D("\n");
|
||||
_selfcare_set_str(root, msg->msg.query_balance.msisdn, "telNumber");
|
||||
}
|
||||
LOG_D("[httpserv] decode query_balance suc\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("[httpserv] decode query_balance fail\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _selfcare_decode_crm_payment(const char *buff, const int len, _rest_msg_s *msg)
|
||||
{
|
||||
msg->msg_type = REST_CRM_PAYMENT_REQ;
|
||||
|
||||
json_t *root = NULL;
|
||||
if(json_parse_document(&root, buff) == JSON_OK)
|
||||
{
|
||||
if(root != NULL && root->type == JSON_OBJECT)
|
||||
{
|
||||
LOG_D("\n");
|
||||
_selfcare_set_str(root, msg->msg.recharge.msisdn, "telNumber");
|
||||
_selfcare_set_u32(root, &msg->msg.recharge.amount, "amount");
|
||||
}
|
||||
LOG_D("[httpserv] decode crm payment suc\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("[httpserv] decode crm payment fail\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _selfcare_decode_sms_deliver(const char *buff, const int len, _rest_msg_s *msg)
|
||||
{
|
||||
msg->msg_type = REST_CRM_SMS_DELIVER_REQ;
|
||||
|
||||
json_t *root = NULL;
|
||||
if(json_parse_document(&root, buff) == JSON_OK)
|
||||
{
|
||||
if(root != NULL && root->type == JSON_OBJECT)
|
||||
{
|
||||
LOG_D("\n");
|
||||
_selfcare_set_str(root, msg->msg.sms_deliver.msisdn, "telNumber");
|
||||
_selfcare_set_str(root, (char *)&msg->msg.sms_deliver.sms_content, "content");
|
||||
}
|
||||
LOG_D("[httpserv] decode sms_dliver suc\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("[httpserv] decode sms_dliver fail\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _selfcare_decode_create_account(const char *buff, const int len, _rest_msg_s *msg)
|
||||
{
|
||||
char buf[128];
|
||||
msg->msg_type = REST_CRM_CREATE_ACCT_REQ;
|
||||
|
||||
json_t *root = NULL;
|
||||
if(json_parse_document(&root, buff) == JSON_OK)
|
||||
{
|
||||
if(root != NULL && root->type == JSON_OBJECT)
|
||||
{
|
||||
LOG_D("\n");
|
||||
_selfcare_set_str(root, msg->msg.create_acct.msisdn, "serviceNbr");
|
||||
_selfcare_set_u32(root, &msg->msg.create_acct.customer_id, "custId");
|
||||
_selfcare_set_u32(root, &msg->msg.create_acct.account_id, "accountId");
|
||||
_selfcare_set_u32(root, &msg->msg.create_acct.product_id, "productInstId");
|
||||
_selfcare_set_u32(root, &msg->msg.create_acct.plan_id, "packageId");
|
||||
_selfcare_set_u32(root, &msg->msg.create_acct.balance, "balance");
|
||||
|
||||
_selfcare_set_str(root, buf, "balanceExpDate");
|
||||
msg->msg.create_acct.expiry_date = TransStrTimeToSecond(buf);
|
||||
|
||||
_selfcare_set_str(root, buf, "birthday");
|
||||
msg->msg.create_acct.birthday = TransStrTimeToSecond(buf);
|
||||
|
||||
msg->msg.create_acct.rent_charge = dba_crm_get_product_rent(1, msg->msg.create_acct.plan_id);
|
||||
|
||||
|
||||
}
|
||||
LOG_D("[httpserv] decode create_account suc\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("[httpserv] decode create_account fail\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef enum CRM_STATUS
|
||||
{
|
||||
CRM_STATUS_FRESH = 1000,
|
||||
CRM_STATUS_NORMAL = 1001,
|
||||
CRM_STATUS_SUSPEND = 1205,
|
||||
CRM_STATUS_DISABLE = 1202,
|
||||
CRM_STATUS_BLACKLIST = 1601,
|
||||
CRM_STATUS_RECYCLE = 1101,
|
||||
|
||||
}_CRM_STATUS;
|
||||
|
||||
typedef enum OCS_STATUS
|
||||
{
|
||||
OCS_STATUS_FRESH = 0,
|
||||
OCS_STATUS_NORMAL = 1,
|
||||
OCS_STATUS_SUSPEND = 2,
|
||||
OCS_STATUS_BLACKLIST = 3,
|
||||
OCS_STATUS_RECYCLE = 4,
|
||||
OCS_STATUS_OPRTRAIL= 5,
|
||||
OCS_STATUS_DISABLE = 6,
|
||||
}_OCS_STATUS;
|
||||
|
||||
int crm_subs_status(u32 crm_status)
|
||||
{
|
||||
int status = CRM_STATUS_NORMAL;
|
||||
|
||||
switch(crm_status)
|
||||
{
|
||||
case CRM_STATUS_FRESH:
|
||||
status = OCS_STATUS_FRESH;
|
||||
break;
|
||||
case CRM_STATUS_NORMAL:
|
||||
status = OCS_STATUS_NORMAL;
|
||||
break;
|
||||
case CRM_STATUS_SUSPEND:
|
||||
status = OCS_STATUS_SUSPEND;
|
||||
break;
|
||||
case CRM_STATUS_DISABLE:
|
||||
status = OCS_STATUS_DISABLE;
|
||||
break;
|
||||
case CRM_STATUS_BLACKLIST:
|
||||
status = OCS_STATUS_BLACKLIST;
|
||||
break;
|
||||
case CRM_STATUS_RECYCLE:
|
||||
status = OCS_STATUS_RECYCLE;
|
||||
break;
|
||||
default:
|
||||
status = OCS_STATUS_SUSPEND;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int _selfcare_decode_update_subs(const char *buff, const int len, _rest_msg_s *msg)
|
||||
{
|
||||
char buf[128];
|
||||
u32 value;
|
||||
msg->msg_type = REST_CRM_UPDATE_SUBS_REQ;
|
||||
|
||||
json_t *root = NULL;
|
||||
if(json_parse_document(&root, buff) == JSON_OK)
|
||||
{
|
||||
if(root != NULL && root->type == JSON_OBJECT)
|
||||
{
|
||||
LOG_D("\n");
|
||||
_selfcare_set_str(root, msg->msg.update_subs.msisdn, "telNumber");
|
||||
if(_selfcare_set_u32(root, &value, "status"))
|
||||
{
|
||||
msg->msg.update_subs.status = value; //crm_subs_status(value);
|
||||
msg->msg.update_subs.optional_flag |= 0x01;
|
||||
}
|
||||
|
||||
if(_selfcare_set_u32(root, &msg->msg.update_subs.balance, "balance"))
|
||||
{
|
||||
msg->msg.update_subs.optional_flag |= 0x02;
|
||||
|
||||
}
|
||||
if(_selfcare_set_str(root, buf, "balanceExpDate"))
|
||||
{
|
||||
msg->msg.update_subs.balance_expiry_date = TransStrTimeToSecond(buf);
|
||||
msg->msg.update_subs.optional_flag |= 0x04;
|
||||
}
|
||||
|
||||
if(_selfcare_set_u32(root, &msg->msg.update_subs.basic_plan_id, "packageId"))
|
||||
{
|
||||
int rent;
|
||||
rent = dba_crm_get_product_rent(1, msg->msg.update_subs.basic_plan_id);
|
||||
msg->msg.update_subs.optional_flag |= 0x08;
|
||||
msg->msg.update_subs.basic_plan_rent = rent;
|
||||
msg->msg.update_subs.optional_flag |= 0x10;
|
||||
}
|
||||
}
|
||||
LOG_D("[httpserv] _selfcare_decode_update_subs suc\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("[httpserv] _selfcare_decode_update_subs fail\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int _selfcare_decode_delete_subs(const char *buff, const int len, _rest_msg_s *msg)
|
||||
{
|
||||
//char buf[128];
|
||||
u32 cause=0;
|
||||
msg->msg_type = REST_CRM_DELETE_SUBS_REQ;
|
||||
|
||||
json_t *root = NULL;
|
||||
if(json_parse_document(&root, buff) == JSON_OK)
|
||||
{
|
||||
if(root != NULL && root->type == JSON_OBJECT)
|
||||
{
|
||||
LOG_D("\n");
|
||||
_selfcare_set_str(root, msg->msg.delete_subs.msisdn, "telNumber");
|
||||
_selfcare_set_u8(root, &msg->msg.delete_subs.account_type, "acctType");
|
||||
_selfcare_set_u32(root, &msg->msg.delete_subs.account_id, "acctID");
|
||||
//_selfcare_set_u32(root, &cause, "reason");
|
||||
|
||||
msg->msg.delete_subs.cause = cause;
|
||||
}
|
||||
LOG_D("[httpserv] _selfcare_decode_deletee_subs suc\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_E("[httpserv] _selfcare_decode_deletee_subs fail\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int selfcare_decode(struct evhttp_request *req,
|
||||
const SELFCARE_URL_E req_type,
|
||||
_rest_msg_s *msg)
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
int (*handle)(const char *buff, const int len, _rest_msg_s *msg);
|
||||
}ss;
|
||||
ss hd[SELFCARE_TYPE_MAX];
|
||||
hd[SELFCARE_AUTHCODE].handle = _selfcare_decode_authcode;
|
||||
hd[SELFCARE_QUERY_USERDATA].handle =_selfcare_decode_query_user_data;
|
||||
hd[SELFCARE_BUNDLE_SUBS].handle = _selfcare_decode_bundle_subs;
|
||||
hd[SELFCARE_BUNDLE_USAGE].handle = _selfcare_decode_bundle_usage;
|
||||
hd[SELFCARE_RECHARGE].handle = _selfcare_decode_recharge;
|
||||
hd[SELFCARE_TRANSFER].handle = _selfcare_decode_transfer;
|
||||
hd[SELFCARE_RECHARGE_CARD].handle = _selfcare_decode_recharge_card;
|
||||
hd[SELFCARE_CHECK_BALANCE].handle = _selfcare_decode_check_balance;
|
||||
hd[SELFCARE_QUERY_BALANCE].handle = _selfcare_decode_query_balance;
|
||||
hd[SELFCARE_CRM_PAYMENT].handle = _selfcare_decode_crm_payment;
|
||||
|
||||
hd[SELFCARE_SMS_DELIVER].handle = _selfcare_decode_sms_deliver;
|
||||
|
||||
hd[SELFCARE_CREATE_ACCT].handle = _selfcare_decode_create_account;
|
||||
hd[SELFCARE_UPDATE_SUBS].handle = _selfcare_decode_update_subs;
|
||||
hd[SELFCARE_DELETE_SUBS].handle = _selfcare_decode_delete_subs;
|
||||
|
||||
|
||||
struct evkeyvalq *headers;
|
||||
struct evkeyval *header;
|
||||
struct evbuffer *buf;
|
||||
|
||||
headers = evhttp_request_get_input_headers(req);
|
||||
for (header = headers->tqh_first; header; header = header->next.tqe_next)
|
||||
{
|
||||
LOG_D(" %s: %s\n", header->key, header->value);
|
||||
}
|
||||
|
||||
|
||||
buf = evhttp_request_get_input_buffer(req);
|
||||
while (evbuffer_get_length(buf))
|
||||
{
|
||||
int n;
|
||||
char cbuf[1024] = {0};
|
||||
n = evbuffer_remove(buf, cbuf, sizeof(cbuf));
|
||||
if (n > 0)
|
||||
{
|
||||
(void)fwrite(cbuf, 1, n, stdout);
|
||||
|
||||
hd[req_type].handle(cbuf, n, msg);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _httpsrv_encode_str(json_t* p_obj, const char* key, const char* value)
|
||||
{
|
||||
json_t *key_child = NULL;
|
||||
json_t *key_value = NULL;
|
||||
|
||||
char* in_key = (char *)malloc(strlen((char *)value)+1);
|
||||
memset (in_key, 0, strlen((char *)value)+1);
|
||||
memcpy (in_key, (char *)value, strlen((char *)value)+1);
|
||||
|
||||
key_child = json_new_string(key);
|
||||
key_value = json_new_string((char *)in_key);
|
||||
json_insert_child(key_child, key_value);
|
||||
json_insert_child(p_obj, key_child);
|
||||
|
||||
free(in_key);
|
||||
}
|
||||
void _httpsrv_encode_u32(json_t* p_obj, const char* key, int value)
|
||||
{
|
||||
char value_str[8] = {0};
|
||||
snprintf(value_str, 8, "%d", value);
|
||||
_httpsrv_encode_str(p_obj, key, value_str);
|
||||
}
|
||||
void _httpsrv_encode_u64(json_t* p_obj, const char* key, u64 value)
|
||||
{
|
||||
char value_str[8] = {0};
|
||||
snprintf(value_str, 8, "%llu", value);
|
||||
_httpsrv_encode_str(p_obj, key, value_str);
|
||||
}
|
||||
void _httpsrv_encode_time(json_t* p_obj, const char* key, u64 value)
|
||||
{
|
||||
struct tm *pTMNowTime;
|
||||
time_t tTemptime;
|
||||
|
||||
tTemptime = value;
|
||||
pTMNowTime = localtime(&tTemptime);
|
||||
if( pTMNowTime == NULL )
|
||||
return ;
|
||||
|
||||
char value_str[32] = {0};
|
||||
snprintf(value_str, 32, "%02d-%02d-%02d %02d:%02d:%02d",
|
||||
pTMNowTime->tm_year + 1900,
|
||||
pTMNowTime->tm_mon + 1,
|
||||
pTMNowTime->tm_mday,
|
||||
pTMNowTime->tm_hour,
|
||||
pTMNowTime->tm_min,
|
||||
pTMNowTime->tm_sec);
|
||||
_httpsrv_encode_str(p_obj, key, value_str);
|
||||
}
|
||||
|
||||
static int _httpsrv_encode_autchcode_resp(const _rest_msg_s *udp_msg, char **buf)
|
||||
{
|
||||
json_t* root = json_new_object();
|
||||
|
||||
_httpsrv_encode_u32(root, "code", udp_msg->msg.send_authcode_res.error_code);
|
||||
_httpsrv_encode_str(root, "message", rest_proxy_errcodemsg(udp_msg->msg.send_authcode_res.error_code));
|
||||
|
||||
|
||||
json_tree_to_string(root, buf);
|
||||
|
||||
LOG_D("[httpsrv-encode] send_authcode_res suc. resp[%s]\n", *buf);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static int _httpsrv_encode_queryusrdata_resp(const _rest_msg_s *udp_msg, char **buf)
|
||||
{
|
||||
json_t* root = json_new_object();
|
||||
|
||||
_httpsrv_encode_u32(root, "code", udp_msg->msg.query_user_data_res.error_code);
|
||||
_httpsrv_encode_str(root, "message", rest_proxy_errcodemsg(udp_msg->msg.query_user_data_res.error_code));
|
||||
|
||||
_httpsrv_encode_u32(root, "status", udp_msg->msg.query_user_data_res.status);
|
||||
_httpsrv_encode_str(root, "remark", udp_msg->msg.query_user_data_res.remark);
|
||||
_httpsrv_encode_str(root, "telNumber", udp_msg->msg.query_user_data_res.msisdn);
|
||||
_httpsrv_encode_str(root, "userGroupName", udp_msg->msg.query_user_data_res.usrGrpName);
|
||||
_httpsrv_encode_u32(root, "balance", udp_msg->msg.query_user_data_res.balance);
|
||||
_httpsrv_encode_time(root, "expireDate", udp_msg->msg.query_user_data_res.mo_expiry);
|
||||
_httpsrv_encode_u32(root, "VoiceMinute", udp_msg->msg.query_user_data_res.mo_voc_min);
|
||||
_httpsrv_encode_u32(root, "remainVoiceMinute", udp_msg->msg.query_user_data_res.remain_mo_voc_min);
|
||||
//_httpsrv_encode_u32(root, "mtVoiceMinute", udp_msg->msg.query_user_data_res.mt_voc_min);
|
||||
//_httpsrv_encode_u32(root, "remainMtVoiceMinute", udp_msg->msg.query_user_data_res.remain_mt_voc_min);
|
||||
_httpsrv_encode_u32(root, "smsVolume", udp_msg->msg.query_user_data_res.total_sms_num);
|
||||
_httpsrv_encode_u32(root, "remainSmsVolume", udp_msg->msg.query_user_data_res.remain_sms_num);
|
||||
_httpsrv_encode_u64(root, "dataVolume", udp_msg->msg.query_user_data_res.total_data_vol);
|
||||
_httpsrv_encode_u64(root, "remainDataVolume", udp_msg->msg.query_user_data_res.remain_data_vol);
|
||||
|
||||
json_tree_to_string(root, buf);
|
||||
|
||||
LOG_D("[httpsrv-encode] query_user_data_res suc. resp[%s]\n", *buf);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
static int _httpsrv_encode_bundlesubs_resp(const _rest_msg_s *udp_msg, char **buf)
|
||||
{
|
||||
json_t* root = json_new_object();
|
||||
|
||||
_httpsrv_encode_u32(root, "code", udp_msg->msg.bundle_subs_res.error_code);
|
||||
_httpsrv_encode_str(root, "message", rest_proxy_errcodemsg(udp_msg->msg.bundle_subs_res.error_code));
|
||||
|
||||
json_tree_to_string(root, buf);
|
||||
|
||||
LOG_D("[httpsrv-encode] bundle_subs_res suc. resp[%s]\n", *buf);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
static int _httpsrv_encode_bundleusage_resp(const _rest_msg_s *udp_msg, char **buf)
|
||||
{
|
||||
json_t* root = json_new_object();
|
||||
|
||||
_httpsrv_encode_u32(root, "code", udp_msg->msg.bundle_usage_res.error_code);
|
||||
_httpsrv_encode_str(root, "message", rest_proxy_errcodemsg(udp_msg->msg.bundle_usage_res.error_code));
|
||||
|
||||
json_t *data_key = json_new_string("data");
|
||||
json_t *data_arr = json_new_array();
|
||||
json_insert_child(root, data_key);
|
||||
json_insert_child(data_key, data_arr);
|
||||
json_t* tmp = json_new_object();
|
||||
_httpsrv_encode_u32(tmp, "moVoiceInSecond", udp_msg->msg.bundle_usage_res.moVoiceInSec);
|
||||
_httpsrv_encode_u32(tmp, "mtVoiceInSecond", udp_msg->msg.bundle_usage_res.mtVoiceInSec);
|
||||
_httpsrv_encode_u32(tmp, "dataVolumeInKB", udp_msg->msg.bundle_usage_res.dataVolInKB);
|
||||
_httpsrv_encode_u32(tmp, "smsVolume", udp_msg->msg.bundle_usage_res.smsNum);
|
||||
_httpsrv_encode_time(tmp, "expiredTimestamp", udp_msg->msg.bundle_usage_res.expiredTime);
|
||||
json_insert_child(data_arr, tmp);
|
||||
|
||||
json_tree_to_string(root, buf);
|
||||
|
||||
LOG_D("[httpsrv-encode] bundle_usage_res suc. resp[%s]\n", *buf);
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
}
|
||||
static int _httpsrv_encode_recharge_resp(const _rest_msg_s *udp_msg, char **buf)
|
||||
{
|
||||
json_t* root = json_new_object();
|
||||
|
||||
int error_code = udp_msg->msg.recharge_res.error_code;
|
||||
if(error_code == 0)
|
||||
error_code = 2001;
|
||||
|
||||
_httpsrv_encode_u32(root, "code", error_code);
|
||||
_httpsrv_encode_str(root, "message", rest_proxy_errcodemsg(udp_msg->msg.recharge_res.error_code));
|
||||
|
||||
_httpsrv_encode_u32(root, "status", udp_msg->msg.recharge_res.status);
|
||||
_httpsrv_encode_u32(root, "balance", udp_msg->msg.recharge_res.balance);
|
||||
_httpsrv_encode_time(root, "expiredTimestamp", udp_msg->msg.recharge_res.expiredTime);
|
||||
|
||||
json_tree_to_string(root, buf);
|
||||
|
||||
LOG_D("[httpsrv-encode] recharge_res suc. resp[%s]\n", *buf);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
static int _httpsrv_encode_transfer_resp(const _rest_msg_s *udp_msg, char **buf)
|
||||
{
|
||||
json_t* root = json_new_object();
|
||||
|
||||
_httpsrv_encode_u32(root, "code", udp_msg->msg.transfer_res.error_code);
|
||||
_httpsrv_encode_str(root, "message", rest_proxy_errcodemsg(udp_msg->msg.transfer_res.error_code));
|
||||
|
||||
_httpsrv_encode_u32(root, "balance", udp_msg->msg.transfer_res.balance);
|
||||
|
||||
json_tree_to_string(root, buf);
|
||||
|
||||
LOG_D("[httpsrv-encode] transfer_res suc. resp[%s]\n", *buf);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
static int _httpsrv_encode_rechargecard_resp(const _rest_msg_s *udp_msg, char **buf)
|
||||
{
|
||||
json_t* root = json_new_object();
|
||||
|
||||
_httpsrv_encode_u32(root, "code", udp_msg->msg.recharge_card_res.error_code);
|
||||
_httpsrv_encode_str(root, "message", rest_proxy_errcodemsg(udp_msg->msg.recharge_card_res.error_code));
|
||||
|
||||
_httpsrv_encode_u32(root, "rechargeAmount", udp_msg->msg.recharge_card_res.rechargeAmount);
|
||||
_httpsrv_encode_u32(root, "balance", udp_msg->msg.recharge_card_res.balance);
|
||||
_httpsrv_encode_time(root, "expiredTimestamp", udp_msg->msg.recharge_card_res.expiredTime);
|
||||
|
||||
json_tree_to_string(root, buf);
|
||||
|
||||
LOG_D("[httpsrv-encode] recharge_card_res suc. resp[%s]\n", *buf);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
static int _httpsrv_encode_checkbalance_resp(const _rest_msg_s *udp_msg, char **buf)
|
||||
{
|
||||
json_t* root = json_new_object();
|
||||
|
||||
_httpsrv_encode_u32(root, "code", udp_msg->msg.check_balance_res.error_code);
|
||||
_httpsrv_encode_str(root, "message", rest_proxy_errcodemsg(udp_msg->msg.check_balance_res.error_code));
|
||||
|
||||
_httpsrv_encode_u32(root, "available", udp_msg->msg.check_balance_res.available);
|
||||
|
||||
json_tree_to_string(root, buf);
|
||||
|
||||
LOG_D("[httpsrv-encode] check_balance_res suc. resp[%s]\n", *buf);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
static int _httpsrv_encode_querybalance_resp(const _rest_msg_s *udp_msg, char **buf)
|
||||
{
|
||||
json_t* root = json_new_object();
|
||||
|
||||
_httpsrv_encode_u32(root, "code", udp_msg->msg.query_balance_res.error_code);
|
||||
_httpsrv_encode_str(root, "message", rest_proxy_errcodemsg(udp_msg->msg.query_balance_res.error_code));
|
||||
|
||||
_httpsrv_encode_u32(root, "status", udp_msg->msg.query_balance_res.status);
|
||||
_httpsrv_encode_u32(root, "balance", udp_msg->msg.query_balance_res.balance);
|
||||
_httpsrv_encode_time(root, "expireDate", udp_msg->msg.query_balance_res.mo_expiry);
|
||||
|
||||
json_tree_to_string(root, buf);
|
||||
|
||||
LOG_D("[httpsrv-encode] query_balance_res suc. resp[%s]\n", *buf);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static int _httpsrv_encode_createaccount_resp(const _rest_msg_s *udp_msg, char **buf)
|
||||
{
|
||||
json_t* root = json_new_object();
|
||||
|
||||
_httpsrv_encode_u32(root, "code", udp_msg->msg.create_acct_res.error_code);
|
||||
_httpsrv_encode_str(root, "message", rest_proxy_errcodemsg(udp_msg->msg.create_acct_res.error_code));
|
||||
|
||||
json_tree_to_string(root, buf);
|
||||
|
||||
LOG_D("[httpsrv-encode] _httpsrv_encode_createaccount_resp suc. resp[%s]\n", *buf);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static int _httpsrv_encode_updatesubs_resp(const _rest_msg_s *udp_msg, char **buf)
|
||||
{
|
||||
json_t* root = json_new_object();
|
||||
|
||||
_httpsrv_encode_u32(root, "code", udp_msg->msg.update_subs_res.error_code);
|
||||
_httpsrv_encode_str(root, "message", rest_proxy_errcodemsg(udp_msg->msg.update_subs_res.error_code));
|
||||
|
||||
json_tree_to_string(root, buf);
|
||||
|
||||
LOG_D("[httpsrv-encode] _httpsrv_encode_updatesubs_resp suc. resp[%s]\n", *buf);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static int _httpsrv_encode_deletesubs_resp(const _rest_msg_s *udp_msg, char **buf)
|
||||
{
|
||||
json_t* root = json_new_object();
|
||||
|
||||
_httpsrv_encode_u32(root, "code", udp_msg->msg.delete_subs_res.error_code);
|
||||
_httpsrv_encode_str(root, "message", rest_proxy_errcodemsg(udp_msg->msg.delete_subs_res.error_code));
|
||||
|
||||
json_tree_to_string(root, buf);
|
||||
|
||||
LOG_D("[httpsrv-encode] _httpsrv_encode_deletesubs_resp suc. resp[%s]\n", *buf);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int selfcare_encode(const SELFCARE_URL_E req_type, const _rest_msg_s *udp_msg, char **buf)
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
int (*handle)(const _rest_msg_s *udp_msg, char **buf);
|
||||
}ss;
|
||||
ss hd[SELFCARE_TYPE_MAX];
|
||||
hd[SELFCARE_AUTHCODE].handle = _httpsrv_encode_autchcode_resp;
|
||||
hd[SELFCARE_QUERY_USERDATA].handle =_httpsrv_encode_queryusrdata_resp;
|
||||
hd[SELFCARE_BUNDLE_SUBS].handle = _httpsrv_encode_bundlesubs_resp;
|
||||
hd[SELFCARE_BUNDLE_USAGE].handle = _httpsrv_encode_bundleusage_resp;
|
||||
hd[SELFCARE_RECHARGE].handle = _httpsrv_encode_recharge_resp;
|
||||
hd[SELFCARE_TRANSFER].handle = _httpsrv_encode_transfer_resp;
|
||||
hd[SELFCARE_RECHARGE_CARD].handle = _httpsrv_encode_rechargecard_resp;
|
||||
hd[SELFCARE_CHECK_BALANCE].handle = _httpsrv_encode_checkbalance_resp;
|
||||
hd[SELFCARE_QUERY_BALANCE].handle = _httpsrv_encode_querybalance_resp;
|
||||
hd[SELFCARE_CREATE_ACCT].handle = _httpsrv_encode_createaccount_resp;
|
||||
hd[SELFCARE_UPDATE_SUBS].handle = _httpsrv_encode_updatesubs_resp;
|
||||
hd[SELFCARE_DELETE_SUBS].handle = _httpsrv_encode_deletesubs_resp;
|
||||
|
||||
|
||||
hd[req_type].handle(udp_msg, buf);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
48
proxy_c/selfcare_endecode.h
Normal file
48
proxy_c/selfcare_endecode.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef __SELFCARE_ENDECODE_H__
|
||||
#define __SELFCARE_ENDECODE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <event2/event.h>
|
||||
#include <event2/http.h>
|
||||
#include <event2/buffer.h>
|
||||
#include <event2/util.h>
|
||||
#include <event2/keyvalq_struct.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <json.h>
|
||||
|
||||
#include "selfcare_httpsrv.h"
|
||||
#include "restapi.h"
|
||||
|
||||
|
||||
int selfcare_decode(struct evhttp_request *req,
|
||||
const SELFCARE_URL_E req_type,
|
||||
_rest_msg_s *msg);
|
||||
|
||||
int selfcare_encode(const SELFCARE_URL_E req_type, const _rest_msg_s *udp_msg, char **buf);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SELFCARE_ENDECODE_H__ */
|
||||
463
proxy_c/selfcare_httpsrv.c
Normal file
463
proxy_c/selfcare_httpsrv.c
Normal file
@@ -0,0 +1,463 @@
|
||||
#include <event2/thread.h>
|
||||
#include "selfcare_httpsrv.h"
|
||||
#include "log.h"
|
||||
#include "selfcare_config.h"
|
||||
|
||||
static selfcare_elem_s g_elems_arr[SELFCARE_TYPE_MAX];
|
||||
|
||||
|
||||
char uri_root[512];
|
||||
|
||||
static const struct table_entry {
|
||||
const char *extension;
|
||||
const char *content_type;
|
||||
} content_type_table[] = {
|
||||
{ "txt", "text/plain" },
|
||||
{ "c", "text/plain" },
|
||||
{ "h", "text/plain" },
|
||||
{ "html", "text/html" },
|
||||
{ "htm", "text/html" },
|
||||
{ "css", "text/css" },
|
||||
{ "gif", "image/gif" },
|
||||
{ "jpg", "image/jpg" },
|
||||
{ "jpeg", "image/jpeg" },
|
||||
{ "png", "image/png" },
|
||||
{ "pdf", "application/pdf" },
|
||||
{ "ps", "application/postscript" },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
/* Try to guess a good content-type for 'path' */
|
||||
const char* guess_content_type(const char *path)
|
||||
{
|
||||
const char *last_period, *extension;
|
||||
const struct table_entry *ent;
|
||||
last_period = strrchr(path, '.');
|
||||
if (!last_period || strchr(last_period, '/'))
|
||||
{
|
||||
goto not_found;
|
||||
}
|
||||
|
||||
extension = last_period + 1;
|
||||
for (ent = &content_type_table[0]; ent->extension; ++ent)
|
||||
{
|
||||
if (!evutil_ascii_strcasecmp(ent->extension, extension))
|
||||
{
|
||||
return ent->content_type;
|
||||
}
|
||||
}
|
||||
|
||||
not_found:
|
||||
return "application/misc";
|
||||
}
|
||||
|
||||
|
||||
/* Callbase used for the /dump URI, and for every non-get request:
|
||||
** dumps all information to stdout and gives base a trivial 200 ok */
|
||||
static void _httpserv_request_cb(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = selfcare_httpsrv_check(req, arg);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
// _httpserv_queue_enter(req, arg);
|
||||
}
|
||||
|
||||
/* This callback gets invoked when we get and http request than doesn't match
|
||||
* any other callback. Like any evhttp server callback, it has a simple job:
|
||||
* it must eventually call evhttp_send_error() or evhttp_send_reply().
|
||||
*/
|
||||
void _httpserv_senddoc_cb(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
struct evbuffer *evb = NULL;
|
||||
const char *docroot = arg;
|
||||
const char *uri = evhttp_request_get_uri(req);
|
||||
struct evhttp_uri *decoded = NULL;
|
||||
const char *path;
|
||||
char *decoded_path;
|
||||
char *whole_path = NULL;
|
||||
size_t len;
|
||||
int fd = -1;
|
||||
struct stat st;
|
||||
|
||||
if (evhttp_request_get_command(req) != EVHTTP_REQ_GET)
|
||||
{
|
||||
_httpserv_request_cb(req, arg);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_D("Got a GET request for <%s>\n", uri);
|
||||
|
||||
/* Decode the URI */
|
||||
decoded = evhttp_uri_parse(uri);
|
||||
if (!decoded)
|
||||
{
|
||||
LOG_E("It's not a good URI, Sneding BADREQUEST\n");
|
||||
evhttp_send_error(req, HTTP_BADREQUEST, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Let's see what path the user asked for. */
|
||||
path = evhttp_uri_get_path(decoded);
|
||||
if (!path)
|
||||
{
|
||||
path = "/";
|
||||
}
|
||||
|
||||
/* We need to decode it, to see what path the user really wanted */
|
||||
decoded_path = evhttp_uridecode(path, 0, NULL);
|
||||
if (decoded_path == NULL)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Don't allow any ".."'s in the path, to avoid exposing stuff outside
|
||||
* of the docroot. This test is both overzealous and underzealous:
|
||||
* it forbids aceptable paths like "/this/one..here", but it doesn't
|
||||
* do anything to prevent symlink following. */
|
||||
if (strstr(decoded_path, ".."))
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
|
||||
len = strlen(decoded_path) + strlen(docroot) + 2;
|
||||
if (!(whole_path = malloc(len)))
|
||||
{
|
||||
perror("malloc");
|
||||
goto err;
|
||||
}
|
||||
evutil_snprintf(whole_path, len, "%s/%s", docroot, decoded_path);
|
||||
|
||||
if (stat(whole_path, &st) < 0)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* This holds the content we're sending */
|
||||
evb = evbuffer_new();
|
||||
|
||||
if (S_ISDIR(st.st_mode))
|
||||
{
|
||||
/* If it's a directory, read the comments and make a little index page */
|
||||
DIR *d;
|
||||
struct dirent *ent;
|
||||
const char *trailing_slash = "";
|
||||
|
||||
if (!strlen(path) || path[strlen(path) - 1] != '/')
|
||||
{
|
||||
trailing_slash = "/";
|
||||
}
|
||||
|
||||
if (!(d = opendir(whole_path)))
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
|
||||
evbuffer_add_printf(evb,
|
||||
"<!DOCTYPE html>\n"
|
||||
"<html>\n "
|
||||
" <head>\n"
|
||||
" <meta charset='utf-8'>\n"
|
||||
" <title>%s</title>\n"
|
||||
" <base href='%s%s'>\n"
|
||||
" </head>\n"
|
||||
" <body>\n"
|
||||
" <h1>%s</h1>\n"
|
||||
" <ul>\n",
|
||||
decoded_path, /* xxx html-escape this. */
|
||||
path, /* xxx html-escape this? */
|
||||
trailing_slash,
|
||||
decoded_path /* xx html-escape this */
|
||||
);
|
||||
|
||||
while ((ent = readdir(d)))
|
||||
{
|
||||
const char *name = ent->d_name;
|
||||
evbuffer_add_printf(evb,
|
||||
" <li><a href=\"%s\">%s</a>\n", name, name);
|
||||
}
|
||||
|
||||
evbuffer_add_printf(evb, "</ul></body></html>\n");
|
||||
closedir(d);
|
||||
evhttp_add_header(evhttp_request_get_output_headers(req),
|
||||
"Content-Type", "text/html");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise it's a file; and it to the buffer to get send via sendfile */
|
||||
const char *type = guess_content_type(decoded_path);
|
||||
if ((fd = open(whole_path, O_RDONLY)) < 0)
|
||||
{
|
||||
perror("open");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (fstat(fd, &st) < 0)
|
||||
{
|
||||
/* Make sure the length still matches, now that we opened the file :/ */
|
||||
perror("fstat");
|
||||
goto err;
|
||||
}
|
||||
evhttp_add_header(evhttp_request_get_output_headers(req),
|
||||
"Content-Type", type);
|
||||
evbuffer_add_file(evb, fd, 0, st.st_size);
|
||||
}
|
||||
|
||||
evhttp_send_reply(req, 200, "OK", evb);
|
||||
goto done;
|
||||
|
||||
err:
|
||||
evhttp_send_error(req, 404, "Document was not found");
|
||||
if (fd >= 0)
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
|
||||
done:
|
||||
if (decoded)
|
||||
{
|
||||
evhttp_uri_free(decoded);
|
||||
}
|
||||
|
||||
if (decoded_path)
|
||||
{
|
||||
free(decoded_path);
|
||||
}
|
||||
|
||||
if (whole_path)
|
||||
{
|
||||
free(whole_path);
|
||||
}
|
||||
|
||||
if (evb)
|
||||
{
|
||||
evbuffer_free(evb);
|
||||
}
|
||||
}
|
||||
|
||||
static int _httpserv_init(int argc, char **argv)
|
||||
{
|
||||
struct event_base *base;
|
||||
struct evhttp *http;
|
||||
struct evhttp_bound_socket *handle;
|
||||
|
||||
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
|
||||
{
|
||||
printf("signal error, errno[%d], error[%s]", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
evthread_use_pthreads();
|
||||
base = event_base_new();
|
||||
if (!base)
|
||||
{
|
||||
printf("Couldn't create an event_base:exiting\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create a new http oject to handle request */
|
||||
http = evhttp_new(base);
|
||||
if (!http)
|
||||
{
|
||||
printf("Couldn't create evhttp.Exiting\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* The /dump URI will dump all requests to stdout and say 200 ok */
|
||||
int i;
|
||||
for(i = SELFCARE_TYPE_MIN; i < SELFCARE_TYPE_MAX; ++i)
|
||||
{
|
||||
if(g_elems_arr[i].handle != NULL)
|
||||
{
|
||||
/* ע<><D7A2><EFBFBD>ص<EFBFBD><D8B5>ϲ㶨<CFB2><E3B6A8><EFBFBD>Ļص<C4BB><D8B5><EFBFBD><EFBFBD><EFBFBD> */
|
||||
evhttp_set_cb(http, g_elems_arr[i].url_addr, g_elems_arr[i].handle, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ע<><D7A2>Ĭ<EFBFBD>ϵĻص<C4BB><D8B5><EFBFBD><EFBFBD><EFBFBD> */
|
||||
evhttp_set_cb(http, "/dump", _httpserv_request_cb, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* We want to accept arbitrary requests, so we need to set a "generic" cb
|
||||
* We can also add callbacks for specific paths */
|
||||
// evhttp_set_gencb(http, _httpserv_senddoc_cb, argv[1]);
|
||||
|
||||
/* Now we teel the evhttp what port to listen on */
|
||||
handle = evhttp_bind_socket_with_handle(http, "0.0.0.0", selfcare_config_get()->http_local_port);
|
||||
if (!handle)
|
||||
{
|
||||
printf("Couldn't bind to port[%d], exiting\n", selfcare_config_get()->http_local_port);
|
||||
return -1;
|
||||
}
|
||||
|
||||
{
|
||||
/* Extract and display the address we're listening on. */
|
||||
struct sockaddr_storage ss;
|
||||
evutil_socket_t fd;
|
||||
ev_socklen_t socklen = sizeof(ss);
|
||||
char addrbuf[128];
|
||||
void *inaddr;
|
||||
const char *addr;
|
||||
int got_port = -1;
|
||||
fd = evhttp_bound_socket_get_fd(handle);
|
||||
memset(&ss, 0, sizeof(ss));
|
||||
if (getsockname(fd, (struct sockaddr *)&ss, &socklen))
|
||||
{
|
||||
perror("getsockname() failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ss.ss_family == AF_INET)
|
||||
{
|
||||
got_port = ntohs(((struct sockaddr_in*)&ss)->sin_port);
|
||||
inaddr = &((struct sockaddr_in*)&ss)->sin_addr;
|
||||
}
|
||||
else if (ss.ss_family == AF_INET6)
|
||||
{
|
||||
got_port = ntohs(((struct sockaddr_in6*)&ss)->sin6_port);
|
||||
inaddr = &((struct sockaddr_in6*)&ss)->sin6_addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Weird address family\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
addr = evutil_inet_ntop(ss.ss_family, inaddr, addrbuf, sizeof(addrbuf));
|
||||
if (addr)
|
||||
{
|
||||
LOG_D("Listening on %s:%d\n", addr, got_port);
|
||||
evutil_snprintf(uri_root, sizeof(uri_root), "http://%s:%d", addr, got_port);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("evutil_inet_ntop failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
event_base_dispatch(base);
|
||||
|
||||
return SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
int selfcare_httpsrv_init(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = _httpserv_init(argc, argv);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void selfcare_httpsrv_uninit(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int selfcare_httpsrv_check(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
return SUCCESS;
|
||||
|
||||
const char *cmdtype;
|
||||
struct evkeyvalq *headers;
|
||||
struct evkeyval *header;
|
||||
struct evbuffer *buf;
|
||||
|
||||
switch (evhttp_request_get_command(req))
|
||||
{
|
||||
case EVHTTP_REQ_GET:
|
||||
cmdtype = "GET";
|
||||
break;
|
||||
case EVHTTP_REQ_POST:
|
||||
cmdtype = "POST";
|
||||
break;
|
||||
case EVHTTP_REQ_HEAD:
|
||||
cmdtype = "HEAD";
|
||||
break;
|
||||
case EVHTTP_REQ_PUT:
|
||||
cmdtype = "PUT";
|
||||
break;
|
||||
case EVHTTP_REQ_DELETE:
|
||||
cmdtype = "DELETE";
|
||||
break;
|
||||
case EVHTTP_REQ_OPTIONS:
|
||||
cmdtype = "OPTIONS";
|
||||
break;
|
||||
case EVHTTP_REQ_TRACE:
|
||||
cmdtype = "TRACE";
|
||||
break;
|
||||
case EVHTTP_REQ_CONNECT:
|
||||
break;
|
||||
case EVHTTP_REQ_PATCH:
|
||||
cmdtype = "PATCH";
|
||||
break;
|
||||
default:
|
||||
cmdtype = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
LOG_D("Received a %s request for %s\nHeader:\n", cmdtype, evhttp_request_get_uri(req));
|
||||
|
||||
headers = evhttp_request_get_input_headers(req);
|
||||
for (header = headers->tqh_first; header; header = header->next.tqe_next)
|
||||
{
|
||||
LOG_D(" %s: %s\n", header->key, header->value);
|
||||
}
|
||||
|
||||
buf = evhttp_request_get_input_buffer(req);
|
||||
puts("Input data: <<<<");
|
||||
while (evbuffer_get_length(buf))
|
||||
{
|
||||
int n;
|
||||
char cbuf[128];
|
||||
n = evbuffer_remove(buf, cbuf, sizeof(cbuf));
|
||||
if (n > 0)
|
||||
{
|
||||
(void)fwrite(cbuf, 1, n, stdout);
|
||||
}
|
||||
}
|
||||
puts(">>>");
|
||||
|
||||
evhttp_send_reply(req, 200, "ok", NULL);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int selfcare_httpsrv_reg(const selfcare_elem_s *elem)
|
||||
{
|
||||
memcpy(&g_elems_arr[elem->url_type], elem, sizeof(selfcare_elem_s));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int selfcare_httpsrv_send(struct evhttp_request *req, const int ret_code, char *buf)
|
||||
{
|
||||
struct evbuffer *evb = NULL;
|
||||
|
||||
evb = evbuffer_new();
|
||||
|
||||
evbuffer_add_printf(evb, "%s", buf);
|
||||
|
||||
evhttp_add_header(evhttp_request_get_output_headers(req),
|
||||
"Content-Type", "application/json");
|
||||
|
||||
evhttp_send_reply(req, ret_code, "OK", evb);
|
||||
|
||||
if (evb)
|
||||
{
|
||||
evbuffer_free(evb);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
82
proxy_c/selfcare_httpsrv.h
Normal file
82
proxy_c/selfcare_httpsrv.h
Normal file
@@ -0,0 +1,82 @@
|
||||
#ifndef __SELFCARE_HTTPSRV_H__
|
||||
#define __SELFCARE_HTTPSRV_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <event2/event.h>
|
||||
#include <event2/http.h>
|
||||
#include <event2/buffer.h>
|
||||
#include <event2/util.h>
|
||||
#include <event2/keyvalq_struct.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <json.h>
|
||||
|
||||
#include "restapi.h"
|
||||
|
||||
typedef enum _SELFCARE_URL_E
|
||||
{
|
||||
SELFCARE_TYPE_MIN = 0,
|
||||
SELFCARE_AUTHCODE, // <20>û<EFBFBD>ע<EFBFBD><D7A2><EFBFBD><EFBFBD><EFBFBD>Žӿ<C5BD>
|
||||
SELFCARE_QUERY_USERDATA, // <20>û<EFBFBD><C3BB><EFBFBD>Ϣ<EFBFBD><CFA2>ѯ<EFBFBD>ӿ<EFBFBD>
|
||||
SELFCARE_BUNDLE_SUBS, // <20>ײͶ<D7B2><CDB6><EFBFBD><EFBFBD>ӿ<EFBFBD>
|
||||
SELFCARE_BUNDLE_USAGE, // <20>Ѷ<EFBFBD><D1B6><EFBFBD><EFBFBD>ײͲ<D7B2>ѯ
|
||||
SELFCARE_RECHARGE, // <20><>ֵ<EFBFBD>ӿ<EFBFBD>
|
||||
SELFCARE_TRANSFER, // ת<>˽ӿ<CBBD>
|
||||
SELFCARE_RECHARGE_CARD, // <20><>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>ֵ<EFBFBD>ӿ<EFBFBD>
|
||||
SELFCARE_CHECK_BALANCE, // <20>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD>ӿ<EFBFBD>
|
||||
SELFCARE_QUERY_BALANCE, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ<EFBFBD>ӿ<EFBFBD>
|
||||
|
||||
SELFCARE_CRM_PAYMENT, // CRM charge interface
|
||||
|
||||
SELFCARE_SMS_DELIVER,
|
||||
|
||||
SELFCARE_CREATE_ACCT,
|
||||
SELFCARE_UPDATE_SUBS,
|
||||
SELFCARE_DELETE_SUBS,
|
||||
|
||||
SELFCARE_TYPE_MAX,
|
||||
}SELFCARE_URL_E;
|
||||
|
||||
|
||||
#define SELFCARE_URL_LEN (128)
|
||||
typedef struct _selfcare_elem_s
|
||||
{
|
||||
SELFCARE_URL_E url_type;
|
||||
char url_addr[SELFCARE_URL_LEN];
|
||||
void (*handle)(struct evhttp_request *req, void *arg);
|
||||
}selfcare_elem_s;
|
||||
|
||||
int selfcare_httpsrv_init(int argc, char **argv);
|
||||
|
||||
void selfcare_httpsrv_uninit(void);
|
||||
|
||||
int selfcare_httpsrv_reg(const selfcare_elem_s *elem);
|
||||
|
||||
int selfcare_httpsrv_check(struct evhttp_request *req, void *arg);
|
||||
|
||||
int selfcare_httpsrv_send(struct evhttp_request *req, const int ret_code, char *buf);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SELFCARE_HTTPSRV_H__ */
|
||||
445
proxy_c/selfcare_proxy.c
Normal file
445
proxy_c/selfcare_proxy.c
Normal file
@@ -0,0 +1,445 @@
|
||||
#include "selfcare_proxy.h"
|
||||
#include "utils_queue.h"
|
||||
#include "selfcare_udp.h"
|
||||
#include "selfcare_endecode.h"
|
||||
#include "selfcare_res.h"
|
||||
#include "log.h"
|
||||
|
||||
extern int get_proxy_run_mode();
|
||||
extern int rest_query_recharge_card_proc( struct rest_msg_s *rest_ptr);
|
||||
extern int rest_query_tariff_proc(struct rest_msg_s *rest_ptr);
|
||||
extern int rest_update_plan_info_proc(struct rest_msg_s *rest_ptr);
|
||||
extern int rest_update_ocs_del_result(struct rest_msg_s *rest_ptr);
|
||||
extern int rest_rent_charge_behalf_on_ocs(struct rest_msg_s *rest_ptr);
|
||||
extern int rest_update_subs_info_proc(struct rest_msg_s *rest_ptr);
|
||||
static int _httpserv_handle_udpresp(char *buff, int len)
|
||||
{
|
||||
/* <20><><EFBFBD><EFBFBD>ocs<63><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8><EFBFBD>udp<64><70>Ϣ */
|
||||
int ret;
|
||||
_rest_msg_s msg;
|
||||
memset(&msg, 0x00, sizeof(msg));
|
||||
ret = decode_rest_api_msg((u8*)buff, len, &msg);
|
||||
if(ret != 1)
|
||||
{
|
||||
LOG_E("[udp-handle] decode ocs resp err.ret[%d]\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(get_proxy_run_mode() == 4)//OCS+CRM mode
|
||||
{
|
||||
if(msg.msg_type == REST_UPDATE_RECHARGE_CARD_REQ)
|
||||
{
|
||||
LOG_E("[udp-handle] proc ocs REST_UPDATE_RECHARGE_CARD_REQ\n");
|
||||
|
||||
rest_query_recharge_card_proc(&msg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(msg.msg_type == REST_CRM_QUERY_TARIFF_REQ)
|
||||
{
|
||||
// LOG_E("[udp-handle] proc ocs REST_CRM_QUERY_TARIFF_REQ\n");
|
||||
|
||||
rest_query_tariff_proc(&msg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(msg.msg_type == REST_CRM_UPDATE_PLAN_INFO_REQ)
|
||||
{
|
||||
// LOG_E("[udp-handle] proc ocs REST_CRM_UPDATE_PLAN_INFO_REQ\n");
|
||||
|
||||
rest_update_plan_info_proc( &msg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(msg.msg_type == REST_CRM_DELETE_SUBS_RES)
|
||||
{
|
||||
// LOG_E("[udp-handle] proc ocs REST_CRM_DELETE_SUBS_RES\n");
|
||||
|
||||
rest_update_ocs_del_result( &msg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
if(msg.msg_type == REST_CRM_RENT_CHARGE)
|
||||
{
|
||||
// LOG_E("[udp-handle] proc ocs REST_CRM_RENT_CHARGE\n");
|
||||
|
||||
rest_rent_charge_behalf_on_ocs( &msg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if(msg.msg_type == REST_CRM_UPDATE_SUBS_REQ)
|
||||
{
|
||||
// LOG_E("[udp-handle] proc ocs REST_CRM_UPDATE_SUBS_INFO_REQ\n");
|
||||
|
||||
rest_update_subs_info_proc( &msg);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
int res_id = msg.header.dst_ref;
|
||||
if(res_id >= SELFCARE_RES_NUM)
|
||||
{
|
||||
LOG_E("[udp-handle] proc ocs resp err. res_id[%d], msg_type=%d\n", res_id, msg.msg_type);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if(g_res_arr[res_id].state != SELFCARE_WAIT_OCS_RESP)
|
||||
{
|
||||
LOG_E("[udp-handle] recv udp err.res_id[%d] state[%s] expect[%s] \n",
|
||||
res_id,
|
||||
selfcare_res_stateprint(g_res_arr[res_id].state),
|
||||
selfcare_res_stateprint(SELFCARE_WAIT_OCS_RESP) );
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
_rest_msg_s *resp = &g_res_arr[res_id].resp;
|
||||
memcpy(resp, &msg, sizeof(msg));
|
||||
if(g_res_arr[res_id].local_init_flag == 1)
|
||||
g_res_arr[res_id].state = SELFCARE_LOCAL_INIT_RESP;
|
||||
else
|
||||
g_res_arr[res_id].state = SELFCARE_WAIT_SEND2SELFCARE_RESP;
|
||||
|
||||
LOG_D("[udp-handle] recv udp suc.res_id[%d] state[%s=>%s]\n",
|
||||
res_id,
|
||||
selfcare_res_stateprint(SELFCARE_WAIT_OCS_RESP),
|
||||
selfcare_res_stateprint(g_res_arr[res_id].state) );
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static int _httpserv_handle_httpreq(struct evhttp_request *req, void *arg, SELFCARE_URL_E req_type)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = selfcare_httpsrv_check(req, arg);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
LOG_E("[httpserv] check failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int res_id;
|
||||
ret = selfcare_res_get(&res_id);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
LOG_D("[httpserv] no res.\n");
|
||||
// send http-resp failed
|
||||
return ret;
|
||||
}
|
||||
|
||||
selfcare_res_s *res = &g_res_arr[res_id];
|
||||
memset(res, 0x00, sizeof(selfcare_res_s));
|
||||
res->id = res_id;
|
||||
res->state = SELFCARE_WAIT_SEND2OCS_REQ;
|
||||
res->req = req;
|
||||
res->arg = arg;
|
||||
res->req_type = req_type;
|
||||
|
||||
LOG_D("[httpserv] res_id[%d] get suc. state[%s] for type[%d]\n", res->id, selfcare_res_stateprint(res->state), req_type);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
selfcare_res_s *selfcare_assign_res()
|
||||
{
|
||||
int res_id, ret;
|
||||
selfcare_res_s *res=NULL;
|
||||
|
||||
ret = selfcare_res_get(&res_id);
|
||||
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
LOG_D("[httpserv] no res.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res = &g_res_arr[res_id];
|
||||
memset(res, 0x00, sizeof(selfcare_res_s));
|
||||
res->id = res_id;
|
||||
|
||||
LOG_D("[httpserv] res_id[%d] get suc. state[%s]\n", res->id, selfcare_res_stateprint(res->state));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void _httpserv_handle_authcode(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
int ret;
|
||||
ret = _httpserv_handle_httpreq(req, arg, SELFCARE_AUTHCODE);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
LOG_E("[httpserv] handle authcode err.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
LOG_D("[httpserv] handle authcode suc.req[%p]\n", req);
|
||||
return ;
|
||||
}
|
||||
|
||||
static void _httpserv_handle_queryuserdata(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
int ret;
|
||||
ret = _httpserv_handle_httpreq(req, arg, SELFCARE_QUERY_USERDATA);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
LOG_E("[httpserv] handle queryuserdata err.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
LOG_D("[httpserv] handle queryuserdata suc.\n");
|
||||
return ;
|
||||
}
|
||||
static void _httpserv_handle_bundlesubs(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
int ret;
|
||||
ret = _httpserv_handle_httpreq(req, arg, SELFCARE_BUNDLE_SUBS);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
LOG_E("[httpserv] handle bundlesubs err.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
LOG_D("[httpserv] handle bundlesubs suc.\n");
|
||||
return ;
|
||||
}
|
||||
static void _httpserv_handle_bundleusage(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
int ret;
|
||||
ret = _httpserv_handle_httpreq(req, arg, SELFCARE_BUNDLE_USAGE);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
LOG_E("[httpserv] handle bundleusage err.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_D("[httpserv] handle bundleusage suc.\n");
|
||||
return ;
|
||||
}
|
||||
static void _httpserv_handle_recharge(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
int ret;
|
||||
ret = _httpserv_handle_httpreq(req, arg, SELFCARE_RECHARGE);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
LOG_E("[httpserv] handle recharge err.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
LOG_D("[httpserv] handle recharge suc.\n");
|
||||
return ;
|
||||
}
|
||||
static void _httpserv_handle_transfer(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
int ret;
|
||||
ret = _httpserv_handle_httpreq(req, arg, SELFCARE_TRANSFER);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
LOG_E("[httpserv] handle transfer err.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
LOG_D("[httpserv] handle transfer suc.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
static void _httpserv_handle_rechargecard(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
int ret;
|
||||
ret = _httpserv_handle_httpreq(req, arg, SELFCARE_RECHARGE_CARD );
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
LOG_E("[httpserv] handle rechargecard err.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
LOG_D("[httpserv] handle rechargecard suc.\n");
|
||||
return ;
|
||||
}
|
||||
static void _httpserv_handle_checkbalance(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
int ret;
|
||||
ret = _httpserv_handle_httpreq(req, arg, SELFCARE_CHECK_BALANCE );
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
LOG_E("[httpserv] handle checkbalance err.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
LOG_D("[httpserv] handle checkbalance suc.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
static void _httpserv_handle_querybalane(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
int ret;
|
||||
ret = _httpserv_handle_httpreq(req, arg, SELFCARE_QUERY_BALANCE );
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
LOG_E("[httpserv] handle querybalane err.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
LOG_D("[httpserv] handle querybalane suc.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
static void _httpserv_handle_payment(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
int ret;
|
||||
ret = _httpserv_handle_httpreq(req, arg, SELFCARE_CRM_PAYMENT );
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
LOG_E("[httpserv] handle crm payment err.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
LOG_D("[httpserv] handle crm payment suc.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
static void _httpserv_handle_smsdeliver(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
int ret;
|
||||
ret = _httpserv_handle_httpreq(req, arg, SELFCARE_SMS_DELIVER);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
LOG_E("[httpserv] handle sms_deliver err.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
LOG_D("[httpserv] handle sms_deliver suc.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
static void _httpserv_handle_createaccount(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
int ret;
|
||||
ret = _httpserv_handle_httpreq(req, arg, SELFCARE_CREATE_ACCT);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
LOG_E("[httpserv] handle create_account err.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
LOG_D("[httpserv] handle create_account suc.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
static void _httpserv_handle_updatesubs(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
int ret;
|
||||
ret = _httpserv_handle_httpreq(req, arg, SELFCARE_UPDATE_SUBS);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
LOG_E("[httpserv] _httpserv_handle_updatesubs err.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
LOG_D("[httpserv] _httpserv_handle_updatesubs suc.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
static void _httpserv_handle_deletesubs(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
int ret;
|
||||
ret = _httpserv_handle_httpreq(req, arg, SELFCARE_DELETE_SUBS);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
LOG_E("[httpserv] _httpserv_handle_updatesubs err.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
LOG_D("[httpserv] _httpserv_handle_updatesubs suc.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
static int _selfcare_proxy_reg(const SELFCARE_URL_E url_type,
|
||||
const char *url_addr,
|
||||
void (*handle)(struct evhttp_request *req, void *arg) )
|
||||
{
|
||||
selfcare_elem_s elem;
|
||||
memset(&elem, 0x00, sizeof(elem));
|
||||
|
||||
elem.url_type = url_type;
|
||||
strncpy(elem.url_addr, url_addr, SELFCARE_URL_LEN);
|
||||
elem.handle = handle;
|
||||
|
||||
return selfcare_httpsrv_reg(&elem);
|
||||
}
|
||||
|
||||
|
||||
int selfcare_proxy_init(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
/* <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
||||
ret = selfcare_config_init(NULL);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* <20><>ʼ<EFBFBD><CABC>udp socket */
|
||||
ret = selfcare_udp_init();
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ע<><D7A2>selfcare<72><65><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD> */
|
||||
ret = _selfcare_proxy_reg(SELFCARE_AUTHCODE, selfcare_config_get()->authcode_url, _httpserv_handle_authcode);
|
||||
ret += _selfcare_proxy_reg(SELFCARE_QUERY_USERDATA, selfcare_config_get()->query_userdata_url, _httpserv_handle_queryuserdata);
|
||||
ret += _selfcare_proxy_reg(SELFCARE_BUNDLE_SUBS, selfcare_config_get()->bundle_subs_url, _httpserv_handle_bundlesubs);
|
||||
ret += _selfcare_proxy_reg(SELFCARE_BUNDLE_USAGE, selfcare_config_get()->bundle_usage_url, _httpserv_handle_bundleusage);
|
||||
ret += _selfcare_proxy_reg(SELFCARE_RECHARGE, selfcare_config_get()->recharge_url, _httpserv_handle_recharge);
|
||||
ret += _selfcare_proxy_reg(SELFCARE_TRANSFER, selfcare_config_get()->transfer_url, _httpserv_handle_transfer);
|
||||
ret += _selfcare_proxy_reg(SELFCARE_RECHARGE_CARD, selfcare_config_get()->recharge_card_url, _httpserv_handle_rechargecard);
|
||||
ret += _selfcare_proxy_reg(SELFCARE_CHECK_BALANCE, selfcare_config_get()->check_balance_url, _httpserv_handle_checkbalance);
|
||||
ret += _selfcare_proxy_reg(SELFCARE_QUERY_BALANCE, selfcare_config_get()->query_balane_url, _httpserv_handle_querybalane);
|
||||
ret += _selfcare_proxy_reg(SELFCARE_CRM_PAYMENT, selfcare_config_get()->payment_url , _httpserv_handle_payment);
|
||||
ret += _selfcare_proxy_reg(SELFCARE_SMS_DELIVER, selfcare_config_get()->sms_deliver_url, _httpserv_handle_smsdeliver);
|
||||
ret += _selfcare_proxy_reg(SELFCARE_CREATE_ACCT, selfcare_config_get()->create_account_url, _httpserv_handle_createaccount);
|
||||
ret += _selfcare_proxy_reg(SELFCARE_UPDATE_SUBS, selfcare_config_get()->update_subs_url, _httpserv_handle_updatesubs);
|
||||
ret += _selfcare_proxy_reg(SELFCARE_DELETE_SUBS, selfcare_config_get()->delete_subs_url, _httpserv_handle_deletesubs);
|
||||
|
||||
/* ע<><D7A2>ocs udp<64><70>Ϣ<EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD> */
|
||||
selfcare_udp_handle_s handle;
|
||||
handle.handle = _httpserv_handle_udpresp;
|
||||
ret = selfcare_udp_reg(&handle);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = selfcare_res_init(argc, argv);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = selfcare_httpsrv_init(argc, argv);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void selfcare_proxy_uninit(void)
|
||||
{
|
||||
selfcare_config_uninit();
|
||||
selfcare_udp_uninit();
|
||||
selfcare_httpsrv_uninit();
|
||||
|
||||
selfcare_res_uninit();
|
||||
}
|
||||
|
||||
23
proxy_c/selfcare_proxy.h
Normal file
23
proxy_c/selfcare_proxy.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef __SELFCARE_PROXY_H__
|
||||
#define __SELFCARE_PROXY_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "selfcare_httpsrv.h"
|
||||
#include "selfcare_config.h"
|
||||
|
||||
|
||||
|
||||
int selfcare_proxy_init(int argc, char **argv);
|
||||
|
||||
void selfcare_proxy_uninit(void);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SELFCARE_PROXY_H__ */
|
||||
379
proxy_c/selfcare_res.c
Normal file
379
proxy_c/selfcare_res.c
Normal file
@@ -0,0 +1,379 @@
|
||||
#include "selfcare_res.h"
|
||||
#include "utils_queue.h"
|
||||
#include "selfcare_udp.h"
|
||||
#include "selfcare_endecode.h"
|
||||
#include "log.h"
|
||||
|
||||
extern selfcare_res_s *selfcare_assign_res();
|
||||
extern void crm_delete_subscriber_profile(char *service_num, int account_type, int account_id);
|
||||
extern int crm_prov_handle_response(selfcare_res_s *res);
|
||||
extern ulong TransStrTimeToSecond(const char *str_time);//YYYY-MM-DD HH:MM:YY
|
||||
extern int dba_crm_get_product_rent(int from, int package_id);
|
||||
extern void _selfcare_udp_process();
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD>*/
|
||||
static queueADT g_res_queue;
|
||||
static int g_res[SELFCARE_RES_NUM];
|
||||
|
||||
/* <20><>Դ */
|
||||
selfcare_res_s g_res_arr[SELFCARE_RES_NUM];
|
||||
|
||||
static int g_res_run_flag;
|
||||
|
||||
static int _selfcare_fsm_sendudp(selfcare_res_s *res)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* 1. <20><><EFBFBD><EFBFBD>selfcareϵͳ<CFB5><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ */
|
||||
_rest_msg_s msg;
|
||||
memset(&msg, 0x00, sizeof(msg));
|
||||
ret = selfcare_decode(res->req,res->req_type, &msg);
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
LOG_E("[httpserv] decode failed\n");
|
||||
return ret;
|
||||
}
|
||||
LOG_D("[httpserv] decode suc. res_id[%d]\n", res->id);
|
||||
|
||||
/* 2. <20><><EFBFBD><EFBFBD> */
|
||||
char buf[1024];
|
||||
int len;
|
||||
msg.header.src_ref = res->id;
|
||||
len = encode_rest(&msg, (u8*)buf);
|
||||
|
||||
if(msg.msg_type == REST_CRM_DELETE_SUBS_REQ)
|
||||
{
|
||||
crm_delete_subscriber_profile(msg.msg.delete_subs.msisdn, msg.msg.delete_subs.account_type, msg.msg.delete_subs.account_id);
|
||||
if(msg.msg.delete_subs.account_type != 1)//not mobile
|
||||
{
|
||||
//return OK to CRM here
|
||||
res->resp.msg_type = REST_CRM_DELETE_SUBS_RES;
|
||||
res->resp.msg.delete_subs_res.result = 0;
|
||||
res->resp.msg.delete_subs_res.error_code = 2001;
|
||||
|
||||
res->state = SELFCARE_WAIT_SEND2SELFCARE_RESP;
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
/* 3. <20><><EFBFBD><EFBFBD>udp<64><70>Ϣ<EFBFBD><CFA2> ocs */
|
||||
if(len > 0)
|
||||
{
|
||||
ret = selfcare_udp_send(buf, len);
|
||||
|
||||
LOG_D("[httpserv] send udp suc.res_id[%d] ret[%d]\n", res->id, ret);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
LOG_E("[httpserv] err.send udp err. res_id[%d]\n", res->id);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
static int _selfcare_fsm_sendudp_local(selfcare_res_s *res, _rest_msg_s msg)
|
||||
{
|
||||
int ret;
|
||||
char buf[1024];
|
||||
int len;
|
||||
|
||||
msg.header.src_ref = res->id;
|
||||
len = encode_rest(&msg, (u8*)buf);
|
||||
|
||||
/* 3. <20><><EFBFBD><EFBFBD>udp<64><70>Ϣ<EFBFBD><CFA2> ocs */
|
||||
if(len > 0)
|
||||
{
|
||||
ret = selfcare_udp_send(buf, len);
|
||||
|
||||
LOG_D("[httpserv] send udp suc.res_id[%d] ret[%d]\n", res->id, ret);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
LOG_E("[httpserv] err.send udp err. res_id[%d]\n", res->id);
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/* <20><><EFBFBD>ͻظ<CDBB><D8B8><EFBFBD>selfcareϵͳ */
|
||||
static void _selfcare_fsm_send2selfcare(const selfcare_res_s *res)
|
||||
{
|
||||
/* <20><><EFBFBD><EFBFBD> */
|
||||
char *buf = NULL;
|
||||
selfcare_encode(res->req_type, &res->resp, &buf);
|
||||
|
||||
/* <20>ظ<EFBFBD> */
|
||||
selfcare_httpsrv_send(res->req, 200, buf);
|
||||
}
|
||||
|
||||
void _selfcare_res_fsm(void)
|
||||
//static void _selfcare_res_fsm(void)
|
||||
{
|
||||
int i;
|
||||
selfcare_res_s *res;
|
||||
|
||||
for(i = 1; i < SELFCARE_RES_NUM; ++i)
|
||||
{
|
||||
res = &g_res_arr[i];
|
||||
res->timer++;
|
||||
switch(res->state)
|
||||
{
|
||||
case SELFCARE_IDLE:
|
||||
break;
|
||||
case SELFCARE_WAIT_SELFCARE_REQ:
|
||||
break;
|
||||
case SELFCARE_WAIT_SEND2OCS_REQ:
|
||||
LOG_D("[httpserv] res_id[%d] state[%s->%s]\n",
|
||||
res->id, selfcare_res_stateprint(res->state), selfcare_res_stateprint(SELFCARE_WAIT_OCS_RESP));
|
||||
|
||||
_selfcare_fsm_sendudp(res);
|
||||
|
||||
res->state = SELFCARE_WAIT_OCS_RESP;
|
||||
res->timer = 0;
|
||||
|
||||
break;
|
||||
case SELFCARE_WAIT_OCS_RESP:
|
||||
/* 3<><33>û<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD> */
|
||||
if(res->timer >= 3000)
|
||||
{
|
||||
// send httpserv time out ???
|
||||
LOG_D("[httpserv] res_id[%d] timeout state[%s->%s]\n",
|
||||
res->id, selfcare_res_stateprint(res->state), selfcare_res_stateprint(SELFCARE_RELEASE));
|
||||
|
||||
res->state = SELFCARE_RELEASE;
|
||||
}
|
||||
|
||||
break;
|
||||
case SELFCARE_WAIT_SEND2SELFCARE_RESP:
|
||||
LOG_D("[httpserv] res_id[%d] state[%s->%s]\n",
|
||||
res->id, selfcare_res_stateprint(res->state), selfcare_res_stateprint(SELFCARE_RELEASE));
|
||||
|
||||
_selfcare_fsm_send2selfcare(res);
|
||||
|
||||
res->state = SELFCARE_RELEASE;
|
||||
res->timer = 0;
|
||||
|
||||
break;
|
||||
case SELFCARE_LOCAL_INIT_REQ:
|
||||
LOG_D("[httpserv] res_id[%d] state[%s->%s]\n",
|
||||
res->id, selfcare_res_stateprint(res->state), selfcare_res_stateprint(SELFCARE_WAIT_OCS_RESP));
|
||||
res->state = SELFCARE_WAIT_OCS_RESP;
|
||||
res->timer = 0;
|
||||
|
||||
// _selfcare_fsm_sendudp(res);
|
||||
|
||||
break;
|
||||
case SELFCARE_LOCAL_INIT_RESP:
|
||||
LOG_D("[httpserv] res_id[%d] state[%s->%s]\n",
|
||||
res->id, selfcare_res_stateprint(res->state), selfcare_res_stateprint(SELFCARE_RELEASE));
|
||||
|
||||
crm_prov_handle_response(res);
|
||||
|
||||
res->state = SELFCARE_RELEASE;
|
||||
res->timer = 0;
|
||||
|
||||
break;
|
||||
case SELFCARE_RELEASE:
|
||||
case SELFCARE_STATE_MAX:
|
||||
default:
|
||||
memset(&g_res_arr[i], 0x00, sizeof(selfcare_res_s));
|
||||
selfcare_res_release(i);
|
||||
LOG_D("[httpserv] release suc. res_id[%d] state[%s]\n",
|
||||
i, selfcare_res_stateprint(SELFCARE_IDLE));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------*/
|
||||
int crm_prov_mobile_prepaid_account(char sub_data[][1024], int cug_id, int user_class)
|
||||
{//user class=1/2 local / tourist
|
||||
selfcare_res_s *res = selfcare_assign_res();
|
||||
_rest_msg_s *msg=NULL, rest_msg;
|
||||
|
||||
if(res == NULL)
|
||||
return 0;
|
||||
|
||||
|
||||
msg = &rest_msg;
|
||||
msg->msg_type = REST_CRM_CREATE_ACCT_REQ;
|
||||
|
||||
strcpy(msg->msg.create_acct.msisdn, sub_data[3]);
|
||||
msg->msg.create_acct.customer_id = atoi(sub_data[6]);
|
||||
msg->msg.create_acct.account_id = atoi(sub_data[7]);
|
||||
msg->msg.create_acct.product_id = atoi(sub_data[8]);
|
||||
msg->msg.create_acct.plan_id = atoi(sub_data[14]);
|
||||
msg->msg.create_acct.user_class = user_class;
|
||||
msg->msg.create_acct.cug_id = cug_id;//atoi(sub_data[16]);
|
||||
msg->msg.create_acct.balance = atoi(sub_data[12]);
|
||||
|
||||
msg->msg.create_acct.expiry_date = TransStrTimeToSecond(sub_data[13]);
|
||||
msg->msg.create_acct.birthday = TransStrTimeToSecond(sub_data[11]);
|
||||
msg->msg.create_acct.rent_charge = dba_crm_get_product_rent(0, msg->msg.create_acct.plan_id);
|
||||
|
||||
res->local_init_db_key = atoi(sub_data[0]);
|
||||
res->local_init_flag = 1;
|
||||
res->local_init_oc = REST_CRM_CREATE_ACCT_REQ;
|
||||
|
||||
_selfcare_fsm_sendudp_local(res, rest_msg);
|
||||
res->state = SELFCARE_LOCAL_INIT_REQ;
|
||||
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
int crm_prov_handle_response(selfcare_res_s *res)
|
||||
{
|
||||
char sql[2048];
|
||||
|
||||
if(res == NULL)
|
||||
return 0;
|
||||
|
||||
switch(res->local_init_oc)
|
||||
{
|
||||
case REST_CRM_CREATE_ACCT_REQ:
|
||||
if(res->resp.msg.create_acct_res.error_code == OCS_RES_SUCCEED)
|
||||
{
|
||||
sprintf(sql, "UPDATE tb_sync_mobile set STATE=2, OPER_RESULT=1 where PRE_ID=%d", res->local_init_db_key);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(sql, "UPDATE tb_sync_mobile set STATE=2, OPER_RESULT=2 where PRE_ID=%d", res->local_init_db_key);
|
||||
}
|
||||
//subs_provisioning_update_result(sql);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------*/
|
||||
|
||||
static void *_selfcare_res_thread(void *data)
|
||||
{
|
||||
prctl(PR_SET_NAME, "selfcare-fsm");
|
||||
|
||||
while(g_res_run_flag)
|
||||
{
|
||||
_selfcare_udp_process();
|
||||
_selfcare_res_fsm();
|
||||
usleep(1000);
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int _selfcare_res_inittask()
|
||||
{
|
||||
pthread_t handle;
|
||||
g_res_run_flag = 1;
|
||||
if(pthread_create(&handle, NULL, _selfcare_res_thread, NULL))
|
||||
{
|
||||
printf("Thread create err !!!\n");
|
||||
return FAILURE;
|
||||
|
||||
if ( pthread_detach(handle) )
|
||||
{
|
||||
printf("Thread detached err !!!\n");
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int selfcare_res_get(int *res_id)
|
||||
{
|
||||
queueElementT elem = QueueDelete(g_res_queue);
|
||||
if(elem == NULL)
|
||||
{
|
||||
LOG_E("[selfcare-res] get err. null\n");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
*res_id = *(int*)elem;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int selfcare_res_release(const int res_id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(res_id>=SELFCARE_RES_NUM)
|
||||
return FAILURE;
|
||||
|
||||
ret = QueueEnter(g_res_queue, &g_res[res_id]);
|
||||
if(ret != SUCCESS_QUEUE)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
const char *selfcare_res_stateprint(selfcare_state_e state)
|
||||
{
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case SELFCARE_IDLE:
|
||||
return "idle";
|
||||
case SELFCARE_WAIT_SELFCARE_REQ:
|
||||
return "wait_selfcare_req";
|
||||
case SELFCARE_WAIT_SEND2OCS_REQ:
|
||||
return "send2ocs_req";
|
||||
case SELFCARE_WAIT_OCS_RESP:
|
||||
return "wait_ocs_resp";
|
||||
case SELFCARE_WAIT_SEND2SELFCARE_RESP:
|
||||
return "wait_send2selfcare_resp";
|
||||
case SELFCARE_LOCAL_INIT_REQ:
|
||||
return "local initiating process - send request";
|
||||
case SELFCARE_LOCAL_INIT_RESP:
|
||||
return "local initiating process-wait for response";
|
||||
case SELFCARE_RELEASE:
|
||||
return "release";
|
||||
default:
|
||||
return "unknow";
|
||||
}
|
||||
return "unknow";
|
||||
}
|
||||
|
||||
int selfcare_res_init(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD>*/
|
||||
g_res_queue = QueueCreate(SELFCARE_RES_NUM);
|
||||
if(g_res_queue == NULL)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
/* <20><><EFBFBD>ؿ<EFBFBD><D8BF><EFBFBD><EFBFBD><EFBFBD>Դ */
|
||||
int i = 0;
|
||||
for(i = 1; i < SELFCARE_RES_NUM; ++i)
|
||||
{
|
||||
g_res[i] = i;
|
||||
ret = QueueEnter(g_res_queue, &g_res[i]);
|
||||
if(ret != SUCCESS_QUEUE)
|
||||
{
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
_selfcare_res_inittask();
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void selfcare_res_uninit(void)
|
||||
{
|
||||
QueueDestroy(g_res_queue);
|
||||
|
||||
g_res_run_flag = 0;
|
||||
}
|
||||
|
||||
66
proxy_c/selfcare_res.h
Normal file
66
proxy_c/selfcare_res.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#ifndef __SELFCARE_RES_H__
|
||||
#define __SELFCARE_RES_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "selfcare_httpsrv.h"
|
||||
#include "selfcare_config.h"
|
||||
|
||||
|
||||
typedef enum _selfcare_state_e
|
||||
{
|
||||
SELFCARE_IDLE = 0,
|
||||
SELFCARE_WAIT_SELFCARE_REQ,
|
||||
SELFCARE_WAIT_SEND2OCS_REQ,
|
||||
SELFCARE_WAIT_OCS_RESP,
|
||||
SELFCARE_WAIT_SEND2SELFCARE_RESP,
|
||||
SELFCARE_LOCAL_INIT_REQ,
|
||||
SELFCARE_LOCAL_INIT_RESP,
|
||||
SELFCARE_RELEASE,
|
||||
SELFCARE_STATE_MAX,
|
||||
}selfcare_state_e;
|
||||
|
||||
#define SELFCARE_RES_NUM (1024)
|
||||
typedef struct _selfcare_res_s
|
||||
{
|
||||
int id;
|
||||
unsigned int timer;
|
||||
|
||||
selfcare_state_e state; /* ״̬ */
|
||||
|
||||
struct evhttp_request *req; /* selfcare <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8> */
|
||||
char *arg; /* libevent <20>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD> */
|
||||
SELFCARE_URL_E req_type; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
||||
|
||||
_rest_msg_s resp; /* OCS <20>ظ<EFBFBD><D8B8><EFBFBD>udp<64><70>Ϣ */
|
||||
int local_init_flag;
|
||||
int local_init_oc;
|
||||
int local_init_db_key;
|
||||
}selfcare_res_s;
|
||||
|
||||
|
||||
extern selfcare_res_s g_res_arr[SELFCARE_RES_NUM];
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դid */
|
||||
int selfcare_res_get(int *res_id);
|
||||
|
||||
/* <20>ͷ<EFBFBD>id */
|
||||
int selfcare_res_release(const int res_id);
|
||||
|
||||
const char *selfcare_res_stateprint(selfcare_state_e state);
|
||||
|
||||
/* <20><>ʼ<EFBFBD><CABC> */
|
||||
int selfcare_res_init(int argc, char **argv);
|
||||
|
||||
/* <20><><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC> */
|
||||
void selfcare_res_uninit(void);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SELFCARE_RES_H__ */
|
||||
122
proxy_c/selfcare_udp.c
Normal file
122
proxy_c/selfcare_udp.c
Normal file
@@ -0,0 +1,122 @@
|
||||
#include "selfcare_udp.h"
|
||||
#include "selfcare_config.h"
|
||||
#include "selfcare_proxy.h"
|
||||
#include "rest_proxy.h"
|
||||
#include "log.h"
|
||||
|
||||
|
||||
/* <20><><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD>udp<64>˿<EFBFBD> */
|
||||
static int g_udp_listfd;
|
||||
/* <20>߳<EFBFBD><DFB3><EFBFBD><EFBFBD>б<EFBFBD><D0B1><EFBFBD> */
|
||||
static int g_udp_runflag;
|
||||
/* <20>յ<EFBFBD>udp<64><70>Ϣ<EFBFBD>ص<EFBFBD> */
|
||||
static selfcare_udp_handle_s g_udp_handle;
|
||||
|
||||
extern int init_socket(unsigned int local_addr, short local_port, char stype, int noblock_flag);
|
||||
|
||||
static int _selfcare_udp_initfd(const unsigned int local_addr, const short local_port)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = init_socket(local_addr, local_port, 0, 1);
|
||||
if(fd <= 0)
|
||||
{
|
||||
LOG_E("[selfcare] init udp fd err. IPPort[%u:%d]\n", local_addr, local_port);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
static void *_selfcare_udp_thread(void *data)
|
||||
{
|
||||
prctl(PR_SET_NAME, "selfcare-udpserver");
|
||||
|
||||
char buf[MAX_BUFFER];
|
||||
int len;
|
||||
int ip;
|
||||
short port;
|
||||
|
||||
while(g_udp_runflag)
|
||||
{
|
||||
len = udp_recv_with_ip_info(g_udp_listfd, buf, MAX_BUFFER, &ip, &port);
|
||||
if(len > 0)
|
||||
{
|
||||
g_udp_handle.handle(buf, len);
|
||||
}
|
||||
|
||||
usleep(10);
|
||||
}
|
||||
pthread_exit(NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void _selfcare_udp_process()
|
||||
{
|
||||
char buf[MAX_BUFFER];
|
||||
int len;
|
||||
int ip;
|
||||
short port;
|
||||
|
||||
{
|
||||
len = udp_recv_with_ip_info(g_udp_listfd, buf, MAX_BUFFER, &ip, &port);
|
||||
if(len > 0)
|
||||
{
|
||||
g_udp_handle.handle(buf, len);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int _selfcare_udp_inittask()
|
||||
{
|
||||
pthread_t handle;
|
||||
g_udp_runflag = 1;
|
||||
if(pthread_create(&handle, NULL, _selfcare_udp_thread, NULL))
|
||||
{
|
||||
printf("Thread create err !!!\n");
|
||||
return FAILURE;
|
||||
|
||||
if ( pthread_detach(handle) )
|
||||
{
|
||||
printf("Thread detached err !!!\n");
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int selfcare_udp_init(void)
|
||||
{
|
||||
/* <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>ؼ<EFBFBD><D8BC><EFBFBD>udp<64>˿<EFBFBD> */
|
||||
g_udp_listfd = _selfcare_udp_initfd(selfcare_config_get()->udp_local_ip, selfcare_config_get()->udp_local_port);
|
||||
|
||||
int ret=SUCCESS;
|
||||
//ret = _selfcare_udp_inittask();
|
||||
if(ret != SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void selfcare_udp_uninit(void)
|
||||
{
|
||||
g_udp_runflag = 0;
|
||||
}
|
||||
|
||||
int selfcare_udp_reg(selfcare_udp_handle_s *handle)
|
||||
{
|
||||
memcpy(&g_udp_handle, handle, sizeof(selfcare_udp_handle_s));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
int selfcare_udp_send(char *buf, short len)
|
||||
{
|
||||
return udp_send(g_udp_listfd, selfcare_config_get()->udp_ocs_ip, selfcare_config_get()->udp_ocs_port, buf, len);
|
||||
}
|
||||
|
||||
26
proxy_c/selfcare_udp.h
Normal file
26
proxy_c/selfcare_udp.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef __SELFCARE_UDP_H__
|
||||
#define __SELFCARE_UDP_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct _selfcare_udp_handle_s
|
||||
{
|
||||
int (*handle)(char *buff, int len);
|
||||
}selfcare_udp_handle_s;
|
||||
|
||||
int selfcare_udp_init(void);
|
||||
|
||||
void selfcare_udp_uninit(void);
|
||||
|
||||
int selfcare_udp_reg(selfcare_udp_handle_s *handle);
|
||||
|
||||
int selfcare_udp_send(char *buf, short len);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SELFCARE_UDP_H__ */
|
||||
53
proxy_c/smcli_client/Makefile
Normal file
53
proxy_c/smcli_client/Makefile
Normal file
@@ -0,0 +1,53 @@
|
||||
|
||||
MODULE = client
|
||||
TYPE = plat
|
||||
|
||||
DBUG_FLAGS_ADD =
|
||||
RELS_FLAGS_ADD =
|
||||
|
||||
##Default commonly as below
|
||||
|
||||
BUILD = lib
|
||||
CFG = debug
|
||||
|
||||
|
||||
PLT_LIB = -DDEBUG
|
||||
|
||||
APP_LIB =
|
||||
LIB_ADD =
|
||||
|
||||
SRC_PATH = ./src
|
||||
INC_PATH = ./src/include
|
||||
PLT_PATH = ../../plat
|
||||
APP_PATH = ../../mss
|
||||
|
||||
OBJ_ADD =
|
||||
TEST_OBJ_PATH =
|
||||
|
||||
PREPROC_CMD =
|
||||
POSTPROC_CMD =
|
||||
|
||||
##---------------------------------------------------------------------##
|
||||
##--------------------------------------
|
||||
##
|
||||
## Make configuration(Customer define)
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
## CCFLAG_SWITCH = on/off => gcc flag show on/off
|
||||
## COVER_NEED = yes/no => PTF cover report needed
|
||||
## COVER_REPORT_PATH = [path ] => PTF cover report path
|
||||
|
||||
CCFLAG_SWITCH = off
|
||||
COVER_NEED = no
|
||||
COVER_REPORT_PATH = ./output
|
||||
|
||||
##---------------------------------------------------------------------##
|
||||
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## include makefile.rules (Do not change)
|
||||
##
|
||||
##--------------------------------------
|
||||
include ./scripts/Makefile.rules
|
||||
342
proxy_c/smcli_client/scripts/Makefile.rules
Normal file
342
proxy_c/smcli_client/scripts/Makefile.rules
Normal file
@@ -0,0 +1,342 @@
|
||||
|
||||
##----------------------------------------------------------##
|
||||
## ##
|
||||
## Universal Makefile Rules ##
|
||||
## ##
|
||||
## Created : Wei Liu 07/03/07 ##
|
||||
## Revision: [Last]Wei Liu 07/07/07 ##
|
||||
## ##
|
||||
##----------------------------------------------------------##
|
||||
|
||||
|
||||
UMAKE_VERSION := V2.0
|
||||
|
||||
##-------------------------------------
|
||||
##
|
||||
## Work Directory : /usr/local/include
|
||||
## Default Target : all
|
||||
##
|
||||
##-------------------------------------
|
||||
default: all
|
||||
.PHONY: all clean rebuild test indent splint doc \
|
||||
dir config check bk lsbk rmbk unzip umakever usage\
|
||||
FORCE
|
||||
.SUFFIXES:
|
||||
|
||||
umakever:
|
||||
@echo "Universal Makefile (UMake) Version: $(UMAKE_VERSION)"
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Makefile CFG defination check
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
ifeq "$(MODULE)" ""
|
||||
$(error Please input the module name (MODULE = )in makefile. )
|
||||
endif
|
||||
|
||||
ifeq "$(CFG)" ""
|
||||
CFG=debug
|
||||
$(warnning No configuration specified for CFG. Defaulting to $(MODULE) - debug. )
|
||||
endif
|
||||
|
||||
ifeq "$(BUILD)" ""
|
||||
BUILD=lib
|
||||
$(warnning No configuration specified for BUILD. Defaulting to create lib$(MODULE).a. )
|
||||
endif
|
||||
|
||||
ifeq "$(SRC_PATH)" ""
|
||||
SRC_PATH=.
|
||||
$(warnning No configuration specified for SRC_PATH. Defaulting to ./. )
|
||||
endif
|
||||
|
||||
COVER_NEED ?= no
|
||||
PLT_PATH ?= ../../plat
|
||||
APP_PATH ?= ../../app
|
||||
TYPE ?= plat
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Gcc Flag for debug or release
|
||||
##
|
||||
##--------------------------------------
|
||||
CC := gcc
|
||||
GCC_CFLAGS := -Wall -MM
|
||||
AR_LINK := ar -r
|
||||
|
||||
RELS_FLAGS_ADD += -DNDEBUG
|
||||
RELEASE_CFLAGS += -g -Wall -I. $(RELS_FLAGS_ADD) -I/usr/include/mysql -L/usr/lib64/mysql -lmysqlclient
|
||||
RELEASE_LINK_CFLAGS = -g $(RELS_FLAGS_ADD) -o
|
||||
DEBUG_CFLAGS += -g -Wall -rdynamic -DDEBUG -I. $(DBUG_FLAGS_ADD) -I/usr/include/mysql -L/usr/lib64/mysql -lmysqlclient -I/usr/include/openssl
|
||||
DEBUG_LINK_CFLAGS = -g -rdynamic -DDEBUG -o
|
||||
|
||||
ifeq "$(COVER_NEED)" "yes"
|
||||
DEBUG_CFLAGS += -fprofile-arcs -ftest-coverage -pg
|
||||
endif
|
||||
|
||||
GCC_CFLAGS=$(DEBUG_CFLAGS)
|
||||
GCC_LINK_CFLAGS=$(DEBUG_LINK_CFLAGS)
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Project setting
|
||||
##
|
||||
##--------------------------------------
|
||||
OBJDIR:=./obj
|
||||
LIBDIR:=./lib
|
||||
UTDIR :=./ut
|
||||
DOCDIR:=./doc
|
||||
DIRBUILD=$(OBJDIR)
|
||||
|
||||
ifeq "$(BUILD)" "lib"
|
||||
BINDIR:=./bin
|
||||
OUTFILE=$(LIBDIR)/lib$(MODULE).a
|
||||
DIRNEED=$(UTDIR) $(DOCDIR)
|
||||
DIRBUILD+=$(LIBDIR)
|
||||
else
|
||||
BINDIR:=.
|
||||
OUTFILE=$(BINDIR)/$(MODULE)
|
||||
DIRNEED=
|
||||
DIRBUILD+=$(BINDIR)
|
||||
endif
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## source , object and dependencies files
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
SRC_SUBDIR := $(shell find $(SRC_PATH) -type d)
|
||||
|
||||
vpath %.c $(SRC_SUBDIR)
|
||||
vpath %.o $(OBJDIR)
|
||||
vpath %.d $(OBJDIR)
|
||||
|
||||
SRC_FULL_PATH = $(foreach dir,$(SRC_SUBDIR),$(wildcard $(dir)/*.c))
|
||||
SRC_FILES = $(foreach file, $(notdir $(SRC_FULL_PATH)) ,$(OBJDIR)/$(file))
|
||||
COMMON_OBJ = $(SRC_FILES:%.c=%.o)
|
||||
|
||||
TEST_OBJ_PATH ?= ../../obj
|
||||
|
||||
TEST_OBJ = $(foreach dir,$(TEST_OBJ_PATH),$(wildcard $(dir)/*.o))
|
||||
|
||||
OBJ=$(COMMON_OBJ) $(OBJ_ADD)
|
||||
ALL_OBJ := $(OBJ) $(TEST_OBJ)
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Lib setting
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
ifeq "$(COVER_NEED)" "yes"
|
||||
LIBCOVER=-lgcov
|
||||
endif
|
||||
|
||||
MODULE_PLT_LIB=$(foreach lib,$(PLT_LIB), -L$(PLT_PATH)/$(lib)/lib/ -l$(lib) )
|
||||
MODULE_PLT_LIB+=-lm
|
||||
|
||||
|
||||
MODULE_APP_LIB=$(foreach lib,$(APP_LIB),-L$(APP_PATH)/$(lib)/lib -l$(lib))
|
||||
|
||||
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Rules
|
||||
##
|
||||
##--------------------------------------
|
||||
CCFLAG_SWITCH ?= off
|
||||
CC_COMPILE =$(CC) $(GCC_CFLAGS) -c $< -o $@
|
||||
CC_PRG_LINK=$(CC) $(GCC_LINK_CFLAGS) $(OUTFILE) $(ALL_OBJ) $(LIBCOVER) $(MODULE_APP_LIB) $(MODULE_PLT_LIB) $(LIB_ADD)
|
||||
CC_LIB_LINK=$(AR_LINK) $(OUTFILE) $(ALL_OBJ)
|
||||
|
||||
COMPILE=$(CC_COMPILE)
|
||||
PRG_LINK=$(CC_PRG_LINK)
|
||||
LIB_LINK=$(CC_LIB_LINK)
|
||||
|
||||
ifeq "$(BUILD)" "exef"
|
||||
LINK=$(PRG_LINK)
|
||||
else
|
||||
LINK=$(LIB_LINK)
|
||||
endif
|
||||
|
||||
# Build rules
|
||||
|
||||
all: preproc start dir $(ALL_OBJ) #prtdebug
|
||||
@echo Linking :$(OUTFILE)
|
||||
ifeq "$(CCFLAG_SWITCH)" "off"
|
||||
@$(LINK)
|
||||
else
|
||||
$(LINK)
|
||||
endif
|
||||
@$(POSTPROC_CMD)
|
||||
@echo -e "\n================================================================================\n"
|
||||
|
||||
sinclude $(DEPENDS)
|
||||
|
||||
release : CC_COMPILE =$(CC) $(RELEASE_CFLAGS) -c $< -o $@
|
||||
release : CC_PRG_LINK=$(CC) $(RELEASE_LINK_CFLAGS) $(OUTFILE) $(ALL_OBJ) $(MODULE_APP_LIB) $(MODULE_PLT_LIB) $(LIB_ADD)
|
||||
release : all
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Make command to use for dependencies
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
MAKE :=make
|
||||
RM :=rm
|
||||
MKDIR :=mkdir
|
||||
|
||||
preproc:
|
||||
@$(PREPROC_CMD)
|
||||
|
||||
start:
|
||||
@echo -e "\n================================================================================\n"
|
||||
@echo "[Building Project]: $(notdir $(MODULE))"
|
||||
ifeq "$(CCFLAG_SWITCH)" "off"
|
||||
@echo "Show Gcc Flags switch = OFF"
|
||||
endif
|
||||
|
||||
prtdebug:
|
||||
@echo "$(MODULE)-$(BUILD)[$(CFG)] build source file:" "$(SRC_FULL_PATH)"
|
||||
@echo SRC_SUBDIR: $(SRC_SUBDIR)
|
||||
@echo SRC_FULL_PATH : $(SRC_FULL_PATH)
|
||||
@echo SRC_FILES : $(SRC_FILES)
|
||||
@echo ALL_OBJ : $(ALL_OBJ)
|
||||
@echo LIB:$(MODULE_PLT_LIB)
|
||||
@echo PLT_LIB: $(PLT_LIB)
|
||||
@echo CCFLAG_SWITCH :$(CCFLAG_SWITCH)
|
||||
|
||||
config: dir
|
||||
|
||||
dir:
|
||||
@$(foreach dir,$(DIRNEED),$(MKDIR) -p $(DIRNEED) --mode=0777; )
|
||||
@$(foreach dir,$(DIRBUILD),$(MKDIR) -p $(dir) --mode=0777; )
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Make Rebuild and clean
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
ifneq "$(PROJ)" ""
|
||||
FRIEND_PROJ := $(shell )
|
||||
endif
|
||||
|
||||
jumprebuild:
|
||||
ifneq "$(PROJ)" ""
|
||||
@cd $(FRIEND_PROJ); mak rebuild ; cd -
|
||||
endif
|
||||
|
||||
# Rebuild this project
|
||||
rebuild: jumprebuild cleanall all
|
||||
|
||||
# Clean this project and all dependencies
|
||||
cleanall: clean
|
||||
|
||||
# Clean this project
|
||||
clean:
|
||||
@echo -e "||--------------------------------------------------------------- "
|
||||
@echo -e "|| Umake clean gcc , lcov, doxygen generated and temporary files. "
|
||||
@echo -e "||--------------------------------------------------------------- "
|
||||
@$(RM) -rf $(OBJDIR) $(OUTFILE) $(COVER_REPORT_PATH) ./doc/doxygen.conf ./doc/html ./doc/latex ./doc/rtf $(foreach dir,$(SRC_SUBDIR),$(dir)/*~)
|
||||
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## indent Makefile.indent
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.indent
|
||||
|
||||
indent:
|
||||
@chmod 777 $(SRC_FULL_PATH)
|
||||
@echo ===================================Indent START=================================
|
||||
@echo
|
||||
@echo "[Indent source file ]: $(SRC_FULL_PATH)"
|
||||
$(call MAKE_INDENT , $(SRC_FULL_PATH))
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## splint makefile.splint
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.splint
|
||||
|
||||
SPLINT_FLAG_SWITCH ?= off
|
||||
|
||||
splint:
|
||||
@chmod 777 $(SRC_FULL_PATH)
|
||||
@echo =================================Splint START==================================
|
||||
@echo
|
||||
ifeq "$(SPLINT_FLAG_SWITCH)" "on"
|
||||
@echo "[Splint flags ]: $(SPLINT_FLAGS)"
|
||||
endif
|
||||
@echo "[Lint Clean Project]: $(notdir $(MODULE))"
|
||||
$(call MAKE_SPLINT, $(SRC_FULL_PATH))
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## doc Makefile.doxygen
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.doxygen
|
||||
|
||||
doc:
|
||||
@chmod 777 $(SRC_FULL_PATH)
|
||||
@echo ==================================Doxygen START=================================
|
||||
@echo
|
||||
$(call MAKE_DOC, $(SRC_FULL_PATH))
|
||||
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## backup Makefile.backup
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.backup
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## cov Makefile.cov
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.cov
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## usage Makefile.usage
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.usage
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Make dependencies
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
$(OBJDIR)/%.d:%.c
|
||||
@$(CC) $< -MM -MD -o $@
|
||||
|
||||
$(OBJDIR)/%.o:%.c
|
||||
|
||||
ifeq "$(CCFLAG_SWITCH)" "off"
|
||||
@echo -e "building: $(notdir $@) \t\t\t\t please wait ..."
|
||||
@$(COMPILE)
|
||||
else
|
||||
$(COMPILE)
|
||||
endif
|
||||
|
||||
DEPENDS=$(COMMON_OBJ:.o=.d)
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## Make force
|
||||
##
|
||||
##--------------------------------------
|
||||
FORCE:
|
||||
|
||||
492
proxy_c/smcli_client/src/client.c
Normal file
492
proxy_c/smcli_client/src/client.c
Normal file
@@ -0,0 +1,492 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "./include/client.h"
|
||||
|
||||
#define CLIENT_CFG "./conf/smcli_client.cfg"
|
||||
|
||||
_client_param_t client_cfg;
|
||||
|
||||
static int smcli_cmd_res=0;
|
||||
static char smcli_result[256];
|
||||
|
||||
int client_read_conf()
|
||||
{
|
||||
char s[80],s1[80];
|
||||
int len;
|
||||
unsigned char conf_state=0xFF;
|
||||
FILE *fpConf;
|
||||
|
||||
memset(&client_cfg, 0x00, sizeof(_client_param_t));
|
||||
|
||||
fpConf = fopen(CLIENT_CFG,"rb");
|
||||
|
||||
if(fpConf == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
strcpy(s,"");
|
||||
strcpy(s1,"");
|
||||
while(fgets(s,1024,fpConf) !=(char *)0)
|
||||
{
|
||||
if( (int *)strchr(s,'#') !=NULL) continue;
|
||||
if( !strlen(s) ) continue;
|
||||
len = strlen(s);
|
||||
if(len < 2) continue;
|
||||
|
||||
if(s[len-1] == 0x0d ||s[len-1] == 0x0a)
|
||||
{
|
||||
if(s[len-2] == 0x0d ||s[len-2] == 0x0a)
|
||||
{
|
||||
s[len-2] = 0;
|
||||
len -= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
s[len-1] = 0;
|
||||
len -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(!strncasecmp(s,"[EMS]",5))
|
||||
{
|
||||
conf_state = 0;
|
||||
continue;
|
||||
}
|
||||
else if(!strncasecmp(s,"[HSS]",5))
|
||||
{
|
||||
conf_state = 1;
|
||||
continue;
|
||||
}
|
||||
else if(!strncasecmp(s,"[AUC]",5))
|
||||
{
|
||||
conf_state = 2;
|
||||
continue;
|
||||
}
|
||||
else if(!strncasecmp(s,"[VMS]",5))
|
||||
{
|
||||
conf_state = 3;
|
||||
continue;
|
||||
}
|
||||
else if(!strncasecmp(s,"[Provision]",11))
|
||||
{
|
||||
conf_state = 4;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(conf_state)
|
||||
{
|
||||
case 0:
|
||||
if(strncasecmp(s,"ems0_ip=",8)==0)
|
||||
{
|
||||
client_cfg.ems_servers.host0_enable = 1;
|
||||
strcpy(client_cfg.ems_servers.host0_ip, &s[8]);
|
||||
//host_ip = inet_addr(&s[8]);
|
||||
}
|
||||
else if(strncasecmp(s,"ems0_port=",10)==0)
|
||||
{
|
||||
client_cfg.ems_servers.host0_port = atoi(&s[10]);
|
||||
}
|
||||
else if(strncasecmp(s,"ems1_ip=",8)==0)
|
||||
{
|
||||
client_cfg.ems_servers.host1_enable = 1;
|
||||
strcpy(client_cfg.ems_servers.host1_ip, &s[8]);
|
||||
//host_ip = inet_addr(&s[8]);
|
||||
}
|
||||
else if(strncasecmp(s,"ems1_port=",10)==0)
|
||||
{
|
||||
client_cfg.ems_servers.host1_port = atoi(&s[10]);
|
||||
}
|
||||
else if(strncasecmp(s,"user_name=",10)==0)
|
||||
{
|
||||
strcpy(client_cfg.ems_servers.user_name, &s[10]);
|
||||
}
|
||||
else if(strncasecmp(s,"password=", 9)==0)
|
||||
{
|
||||
strcpy(client_cfg.ems_servers.password, &s[9]);
|
||||
}
|
||||
else if(strncasecmp(s,"connect_hss=",12)==0)
|
||||
{
|
||||
client_cfg.connect_configured[SYS_T_HSS] = 1;
|
||||
strcpy(client_cfg.connect_command[SYS_T_HSS], &s[12]);
|
||||
}
|
||||
else if(strncasecmp(s,"connect_auc=",12)==0)
|
||||
{
|
||||
client_cfg.connect_configured[SYS_T_AUC] = 1;
|
||||
strcpy(client_cfg.connect_command[SYS_T_AUC], &s[12]);
|
||||
}
|
||||
else if(strncasecmp(s,"connect_vms=",12)==0)
|
||||
{
|
||||
client_cfg.connect_configured[SYS_T_VMS] = 1;
|
||||
strcpy(client_cfg.connect_command[SYS_T_VMS], &s[12]);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
strcpy(client_cfg.cli_command[SYS_T_HSS], s);
|
||||
break;
|
||||
case 2:
|
||||
strcpy(client_cfg.cli_command[SYS_T_AUC], s);
|
||||
break;
|
||||
case 3:
|
||||
strcpy(client_cfg.cli_command[SYS_T_VMS], s);
|
||||
break;
|
||||
case 4:
|
||||
if(strncasecmp(s,"enable", 6) == 0)
|
||||
{
|
||||
client_cfg.provsioning_flag = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fpConf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int rest_provsioning_enabled()
|
||||
{
|
||||
return client_cfg.provsioning_flag;
|
||||
}
|
||||
|
||||
int smcli_reset_result()
|
||||
{
|
||||
smcli_cmd_res = 0;
|
||||
}
|
||||
|
||||
int smcli_get_result(char* result_des)
|
||||
{
|
||||
if(smcli_cmd_res != 0)
|
||||
strcpy(result_des, smcli_result);
|
||||
|
||||
return smcli_cmd_res;
|
||||
}
|
||||
|
||||
int smcli_connect_ems()
|
||||
{
|
||||
if(client_cfg.ems_servers.host0_enable)
|
||||
tcp_connect_server(client_cfg.ems_servers.host0_ip, client_cfg.ems_servers.host0_port);
|
||||
else if(client_cfg.ems_servers.host1_enable)
|
||||
tcp_connect_server(client_cfg.ems_servers.host1_ip, client_cfg.ems_servers.host1_port);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void smcli_send_user_name_pwd(int flag)
|
||||
{
|
||||
char user_name[128];
|
||||
char password[128];
|
||||
|
||||
if(flag == 0)
|
||||
{
|
||||
sprintf(user_name, "%s\r\n", client_cfg.ems_servers.user_name);
|
||||
tcp_send_msg(user_name, strlen(user_name));
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(password, "%s\r\n", client_cfg.ems_servers.password);
|
||||
tcp_send_msg(password, strlen(password));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void smcli_connect_cn_nodes(int sys_type)
|
||||
{
|
||||
char command[128];
|
||||
|
||||
sprintf(command, "%s\r\n", client_cfg.connect_command[sys_type]);
|
||||
tcp_send_msg(command, strlen(command));
|
||||
|
||||
}
|
||||
|
||||
void smcli_send_command(char *command)
|
||||
{
|
||||
tcp_send_msg(command, strlen(command));
|
||||
|
||||
smcli_reset_result();
|
||||
|
||||
}
|
||||
|
||||
void crm_create_vms_account(char *number)
|
||||
{
|
||||
char cli_command[1024];
|
||||
|
||||
sprintf(cli_command,"create vmsSubscriber -msisdn %s", number);
|
||||
|
||||
smcli_send_command(cli_command);
|
||||
}
|
||||
|
||||
void crm_prov_hlr_auc_vms_account(char sub_data[][1024])
|
||||
{//PRE_ID, IMSI, SERVICE_NBR, KI, OPC, ACCT_TYPE,CUST_ID, ACCT_ID, PRD_INST_ID, MOBILE_TYPE, VMS_FLAG
|
||||
char cli_command[1024];
|
||||
|
||||
if(1)//HLR
|
||||
{
|
||||
sprintf(cli_command,"create subscriber -imsi %s -msisdn %s -eps_user_tpl def_eps -impi %s@ims.mnc010.mcc505.3gppnetwork.org",
|
||||
sub_data[2], sub_data[3], sub_data[2]);
|
||||
|
||||
smcli_send_command(cli_command);
|
||||
}
|
||||
|
||||
sleep(2);
|
||||
if(1)
|
||||
{
|
||||
if(sub_data[5][0] == 0)
|
||||
sprintf(cli_command,"create aucSubscriber -imsi %s -ki %s", sub_data[2], sub_data[4]);
|
||||
else
|
||||
sprintf(cli_command,"create aucSubscriber -imsi %s -ki %s -opc %s", sub_data[2], sub_data[4], sub_data[5]);
|
||||
|
||||
smcli_send_command(cli_command);
|
||||
}
|
||||
|
||||
sleep(2);
|
||||
|
||||
if(atoi(sub_data[10]))//VMS enabled
|
||||
{
|
||||
crm_create_vms_account(sub_data[3]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int smcli_link_fsm()
|
||||
{
|
||||
u_char recvbuf[1024];
|
||||
int len = 0;
|
||||
|
||||
int state = 0;
|
||||
|
||||
state = client_cfg.smcli_link_state;
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case 0: //do nothing
|
||||
break;
|
||||
case 1:
|
||||
len = tcp_recv_msg(recvbuf);
|
||||
if(len>0)
|
||||
{
|
||||
if(strstr(recvbuf, "username:"))
|
||||
{
|
||||
smcli_send_user_name_pwd(0);
|
||||
}
|
||||
|
||||
//if(strstr(recvbuf, "Welcome to"))
|
||||
client_cfg.smcli_link_state = 2;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
len = tcp_recv_msg(recvbuf);
|
||||
if(len>0)
|
||||
{
|
||||
if(strstr(recvbuf, "username:"))
|
||||
{
|
||||
smcli_send_user_name_pwd(0);
|
||||
}
|
||||
else if(strstr(recvbuf,"password:"))
|
||||
{
|
||||
smcli_send_user_name_pwd(1);
|
||||
client_cfg.smcli_link_state = 3;
|
||||
client_cfg.smcli_verified = 1;
|
||||
}
|
||||
else if(strstr(recvbuf, "Login incorrect"))
|
||||
{
|
||||
printf("error username/password\r\n");
|
||||
exit(128);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
len = tcp_recv_msg(recvbuf);
|
||||
if(len>0)
|
||||
{
|
||||
if(strstr(recvbuf,"CLI>")) //login succeed
|
||||
{
|
||||
client_cfg.smcli_link_state = 10;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
if(client_cfg.connect_configured[SYS_T_HSS])
|
||||
{
|
||||
smcli_connect_cn_nodes(SYS_T_HSS);
|
||||
client_cfg.smcli_link_state = 11;
|
||||
}
|
||||
else
|
||||
{
|
||||
client_cfg.smcli_link_state = 20;
|
||||
}
|
||||
|
||||
break;
|
||||
case 11:
|
||||
len = tcp_recv_msg(recvbuf);
|
||||
if(len>0)
|
||||
{
|
||||
if(strstr(recvbuf,"Login incorrec"))
|
||||
{
|
||||
printf("connect hlr failed\r\n");
|
||||
}
|
||||
client_cfg.smcli_link_state = 12;
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
len = tcp_recv_msg(recvbuf);
|
||||
if(len>0)
|
||||
{
|
||||
if(strstr(recvbuf,"CLI>")) //input mode
|
||||
{
|
||||
client_cfg.smcli_link_state = 20;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 20:
|
||||
if(client_cfg.connect_configured[SYS_T_AUC])
|
||||
{
|
||||
smcli_connect_cn_nodes(SYS_T_AUC);
|
||||
client_cfg.smcli_link_state = 21;
|
||||
}
|
||||
else
|
||||
{
|
||||
client_cfg.smcli_link_state = 30;
|
||||
}
|
||||
break;
|
||||
case 21:
|
||||
len = tcp_recv_msg(recvbuf);
|
||||
if(len>0)
|
||||
{
|
||||
if(strstr(recvbuf,"Login incorrec") )
|
||||
{
|
||||
printf("connect auc failed\r\n");
|
||||
}
|
||||
client_cfg.smcli_link_state = 22;
|
||||
}
|
||||
break;
|
||||
case 22:
|
||||
len = tcp_recv_msg(recvbuf);
|
||||
if(len>0)
|
||||
{
|
||||
if(strstr(recvbuf,"CLI>")) //input mode
|
||||
{
|
||||
client_cfg.smcli_link_state = 30;//100;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 30:
|
||||
if(client_cfg.connect_configured[SYS_T_VMS])
|
||||
{
|
||||
smcli_connect_cn_nodes(SYS_T_VMS);
|
||||
client_cfg.smcli_link_state = 31;
|
||||
}
|
||||
else
|
||||
{
|
||||
client_cfg.smcli_link_state = 100;
|
||||
}
|
||||
|
||||
break;
|
||||
case 31:
|
||||
len = tcp_recv_msg(recvbuf);
|
||||
if(len>0)
|
||||
{
|
||||
if(strstr(recvbuf,"Login incorrec") )
|
||||
{
|
||||
printf("connect vms failed\r\n");
|
||||
}
|
||||
client_cfg.smcli_link_state = 32;
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
len = tcp_recv_msg(recvbuf);
|
||||
if(len>0)
|
||||
{
|
||||
if(strstr(recvbuf,"CLI>")) //input mode
|
||||
{
|
||||
client_cfg.smcli_link_state = 100;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 100://normal state, can handle cli command
|
||||
len = tcp_recv_msg(recvbuf);
|
||||
if(len>6)
|
||||
{
|
||||
if(strstr(recvbuf,"Login incorrect"))
|
||||
{
|
||||
printf("smcli link is discounneted\r\n");
|
||||
client_cfg.smcli_link_state = 1;
|
||||
|
||||
smcli_cmd_res = 2;
|
||||
strcpy(smcli_result, recvbuf);
|
||||
}
|
||||
else if(strstr(recvbuf, "success"))
|
||||
{
|
||||
smcli_cmd_res = 1;
|
||||
strcpy(smcli_result, recvbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
smcli_cmd_res = 2;
|
||||
strcpy(smcli_result, recvbuf);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void smlci_connection_check()
|
||||
{
|
||||
if(client_cfg.client_connected == 1)
|
||||
return;
|
||||
|
||||
if(is_tcp_connected()>=0)
|
||||
{
|
||||
client_cfg.client_connected = 1;
|
||||
client_cfg.smcli_link_state = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void smcli_connection_is_broken()
|
||||
{
|
||||
client_cfg.client_connected = 0;
|
||||
|
||||
client_cfg.smcli_link_state = 0;
|
||||
client_cfg.smcli_verified = 0;
|
||||
|
||||
}
|
||||
|
||||
int smcli_client_thread(void *param)
|
||||
{
|
||||
static int smcli_timer= 0;
|
||||
|
||||
client_read_conf();
|
||||
|
||||
smcli_connect_ems();
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(smcli_timer % 10000)
|
||||
{
|
||||
tcp_check_connection();
|
||||
|
||||
smlci_connection_check();
|
||||
smcli_timer = 0;
|
||||
}
|
||||
|
||||
smcli_link_fsm();
|
||||
|
||||
smcli_timer ++;
|
||||
usleep(10000);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
50
proxy_c/smcli_client/src/include/client.h
Normal file
50
proxy_c/smcli_client/src/include/client.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef _SMCLI_CLIENT_H
|
||||
#define _SMCLI_CLIENT_H
|
||||
|
||||
#define CLI_COMMAND_LEN 8192
|
||||
#define CONNECT_COMMAND_LEN 128
|
||||
|
||||
typedef enum ACCT_TYPE
|
||||
{
|
||||
ACCT_T_MOBILE,
|
||||
ACCT_T_PSTN,
|
||||
ACCT_T_ADSL,
|
||||
}_ACCT_TYPE;
|
||||
|
||||
typedef enum SYS_TYPE
|
||||
{
|
||||
SYS_T_EMS,
|
||||
SYS_T_HSS,
|
||||
SYS_T_AUC,
|
||||
SYS_T_VMS,
|
||||
SYS_T_PSTN,
|
||||
SYS_T_ADSL,
|
||||
SYS_T_MAX,
|
||||
}_SYS_TYPE;
|
||||
|
||||
typedef struct server_param_t
|
||||
{
|
||||
u_char host0_enable;
|
||||
char host0_ip[16];
|
||||
u_short host0_port;
|
||||
u_char host1_enable;
|
||||
char host1_ip[16];
|
||||
u_short host1_port;
|
||||
char user_name[16];
|
||||
char password[16];
|
||||
}server_param_t;
|
||||
|
||||
|
||||
typedef struct client_param_t
|
||||
{
|
||||
int client_connected;
|
||||
int smcli_verified;
|
||||
int smcli_link_state;
|
||||
int provsioning_flag;
|
||||
server_param_t ems_servers;
|
||||
char connect_configured[SYS_T_MAX];
|
||||
char connect_command[SYS_T_MAX][CONNECT_COMMAND_LEN];
|
||||
char cli_command[SYS_T_MAX][CLI_COMMAND_LEN];
|
||||
}_client_param_t;
|
||||
|
||||
#endif
|
||||
143
proxy_c/smcli_client/src/tcp_client.c
Normal file
143
proxy_c/smcli_client/src/tcp_client.c
Normal file
@@ -0,0 +1,143 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
|
||||
#define RES_LENGTH 10240
|
||||
|
||||
static int client_fd=0;
|
||||
static int client_connect_flag = -1;
|
||||
static char server_ip[16];
|
||||
static short server_port;
|
||||
|
||||
int connect_socket(char * server,int serverPort);
|
||||
int send_msg(int sockfd,char * sendBuff);
|
||||
char * recv_msg(int sockfd);
|
||||
int close_socket(int sockfd);
|
||||
|
||||
int init_socketfd()
|
||||
{
|
||||
int sockfd = -1;
|
||||
|
||||
if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0){
|
||||
herror("Init socket error!");
|
||||
}
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
void tcp_init_client_fd()
|
||||
{
|
||||
client_fd = init_socketfd();
|
||||
|
||||
}
|
||||
|
||||
void tcp_connect_server(char *ip, u_short port)
|
||||
{
|
||||
tcp_init_client_fd();
|
||||
|
||||
strcpy(server_ip, ip);
|
||||
server_port = port;
|
||||
client_connect_flag = connect_socket(ip, port);
|
||||
}
|
||||
|
||||
int is_tcp_connected()
|
||||
{
|
||||
return client_connect_flag;
|
||||
}
|
||||
|
||||
/* * ********************************************************/
|
||||
int connect_socket(char * server,int serverPort)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
struct hostent * phost;
|
||||
|
||||
bzero(&addr,sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(serverPort);
|
||||
addr.sin_addr.s_addr = inet_addr(server);
|
||||
|
||||
if(addr.sin_addr.s_addr == INADDR_NONE){
|
||||
phost = (struct hostent*)gethostbyname(server);
|
||||
if(phost==NULL){
|
||||
herror("Init socket s_addr error!");
|
||||
return -1;
|
||||
}
|
||||
addr.sin_addr.s_addr =((struct in_addr*)phost->h_addr)->s_addr;
|
||||
}
|
||||
if(connect(client_fd,(struct sockaddr*)&addr, sizeof(addr))<0)
|
||||
{
|
||||
// perror("Connect server fail!");
|
||||
return -1; //0<><30>ʾ<EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD>-1<><31>ʾʧ<CABE><CAA7>
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int tcp_send_msg( u_char *sendbuf, short len)
|
||||
{
|
||||
int sendSize=0;
|
||||
|
||||
if((sendSize=send(client_fd,sendbuf,len,MSG_NOSIGNAL))<=0){
|
||||
close_socket(client_fd);
|
||||
herror("Send msg error!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sendSize;
|
||||
}
|
||||
|
||||
int tcp_recv_msg(u_char *recvbuf)
|
||||
{
|
||||
int recLenth=0;
|
||||
|
||||
if(( recLenth=recv(client_fd,recvbuf, BUF_SIZE,0))==-1 )
|
||||
{
|
||||
close_socket(client_fd);
|
||||
return -1;
|
||||
}
|
||||
if(recLenth == 0)
|
||||
{
|
||||
close_socket(client_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( recLenth>0)
|
||||
recvbuf[recLenth] = 0;
|
||||
return recLenth;
|
||||
}
|
||||
|
||||
int tcp_check_connection()
|
||||
{
|
||||
if(client_connect_flag == -1)
|
||||
{
|
||||
client_connect_flag = connect_socket(server_ip, server_port);
|
||||
}
|
||||
|
||||
return client_connect_flag;
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
*<2A>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD>
|
||||
* **********************************************/
|
||||
int close_socket(int sockfd)
|
||||
{
|
||||
client_connect_flag = -1;
|
||||
close(sockfd);
|
||||
|
||||
smcli_connection_is_broken();
|
||||
|
||||
tcp_init_client_fd();
|
||||
|
||||
return 0;
|
||||
}
|
||||
122
proxy_c/sock_if.c
Normal file
122
proxy_c/sock_if.c
Normal file
@@ -0,0 +1,122 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <netinet/ether.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <sys/types.h>
|
||||
#include <net/if.h>
|
||||
#include <linux/sockios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#define INET_UDP 0
|
||||
|
||||
int init_socket(unsigned int local_addr, short local_port, char stype, int noblock_flag)
|
||||
{
|
||||
struct sockaddr_in sin_addr;
|
||||
int on=1, sockfd;
|
||||
|
||||
memset((void *)&sin_addr,0x00,sizeof(struct sockaddr_in));
|
||||
sin_addr.sin_family = AF_INET;
|
||||
sin_addr.sin_port = htons(local_port);
|
||||
if(local_addr == 0)
|
||||
sin_addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
else
|
||||
sin_addr.sin_addr.s_addr = local_addr;
|
||||
//sin_addr.sin_addr.s_addr = htonl(local_addr);
|
||||
|
||||
bzero((void *)&(sin_addr.sin_zero),8);
|
||||
|
||||
if(stype == INET_UDP)
|
||||
sockfd = socket(AF_INET,SOCK_DGRAM,0);
|
||||
else
|
||||
sockfd = socket(AF_INET,SOCK_STREAM,0);
|
||||
|
||||
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
|
||||
|
||||
if(stype != INET_UDP)
|
||||
{
|
||||
setsockopt(sockfd,IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
|
||||
setsockopt(sockfd,SOL_TCP, TCP_NODELAY, &on, sizeof(on));
|
||||
}
|
||||
if(noblock_flag)
|
||||
fcntl(sockfd,F_SETFL,O_NONBLOCK);
|
||||
|
||||
bind(sockfd,(struct sockaddr*)&sin_addr,sizeof(struct sockaddr));
|
||||
|
||||
// listen(sockfd,1);
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
int setnodelay(int fd)
|
||||
{
|
||||
int on=1;
|
||||
|
||||
setsockopt(fd,IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
|
||||
setsockopt(fd,SOL_TCP, TCP_NODELAY, &on, sizeof(on));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void set_peer_addr(struct sockaddr_in *peer_addr, char *peer_ip,short peer_port)
|
||||
{
|
||||
peer_addr->sin_family = AF_INET;
|
||||
peer_addr->sin_port = htons(peer_port);
|
||||
peer_addr->sin_addr.s_addr = inet_addr(peer_ip);
|
||||
bzero((void *)&(peer_addr->sin_zero),8);
|
||||
|
||||
}/*set_config*/
|
||||
|
||||
int udp_send(int fd, int peer_ip, short peer_port, char *buf, short len)
|
||||
{
|
||||
struct sockaddr_in sin_addr;
|
||||
int ret;
|
||||
|
||||
memset(&sin_addr, 0, sizeof(struct sockaddr));
|
||||
|
||||
sin_addr.sin_addr.s_addr = peer_ip;
|
||||
sin_addr.sin_port = htons(peer_port);
|
||||
|
||||
ret = sendto(fd, buf, len, 0, (struct sockaddr*)&sin_addr, sizeof(struct sockaddr));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int udp_recv(int fd, char *buf, short MAX_LEN)
|
||||
{
|
||||
int len, addr_len;
|
||||
struct sockaddr_in sin_addr;
|
||||
|
||||
addr_len = sizeof(struct sockaddr);
|
||||
memset(&sin_addr, 0, addr_len);
|
||||
|
||||
len = recvfrom(fd, buf, MAX_LEN, 0, (struct sockaddr*)&sin_addr, (socklen_t*)&addr_len);
|
||||
if(len < 0)
|
||||
return 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
int udp_recv_with_ip_info(int fd, char *buf, short MAX_LEN, int *peer_ip, short *peer_port)
|
||||
{
|
||||
int len, addr_len;
|
||||
struct sockaddr_in sin_addr;
|
||||
|
||||
addr_len = sizeof(struct sockaddr);
|
||||
memset(&sin_addr, 0, addr_len);
|
||||
|
||||
len = recvfrom(fd, buf, MAX_LEN, 0, (struct sockaddr*)&sin_addr, (socklen_t*)&addr_len);
|
||||
if(len < 0)
|
||||
return 0;
|
||||
|
||||
*peer_ip = sin_addr.sin_addr.s_addr;
|
||||
*peer_port = htons(sin_addr.sin_port);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
98
proxy_c/tcp/Makefile
Normal file
98
proxy_c/tcp/Makefile
Normal file
@@ -0,0 +1,98 @@
|
||||
|
||||
##----------------------------------------------------------##
|
||||
## ##
|
||||
## Universal Makefile for module template : V1.6.3 ##
|
||||
## ##
|
||||
## Created : Wei Liu 07/04/11 ##
|
||||
## Revision: [Last]Wei Liu 07/07/07 ##
|
||||
## ##
|
||||
##----------------------------------------------------------##
|
||||
|
||||
##---------------------------------------------------------------------##
|
||||
##--------------------------------------
|
||||
##
|
||||
## Project correlation(Customer define)
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
## MODULE= [Module Name]
|
||||
## TYPE = app/plat => Module Type
|
||||
|
||||
## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Debug ]
|
||||
## DBUG_FLAGS_ADD = [Module Define Gcc Flags for Release]
|
||||
|
||||
## BUILD = lib/exef => Output file format
|
||||
## CFG = debug/release => Build Configuration
|
||||
|
||||
## SRC_PATH = [Source file path]
|
||||
## INC_PATH = [Include file path]
|
||||
## APP_PATH = [App Module path]
|
||||
## PLT_PATH = [Plat Module path]
|
||||
|
||||
## PLT_LIB = [Needed plat lib for Link] => just for test or wxc2main
|
||||
## APP_LIB = [Needed app lib for Link] => just for test or wxc2main
|
||||
## LIB_ADD = [Needed Extend lib for Link] => just for test or wxc2main
|
||||
|
||||
## PLT_LIB e.g. = haepub fsm mng proto kernel aif mgc mgcp sip rtp \
|
||||
## 8ecp bicc smpp xapp tcap mtp3 m2ua \
|
||||
## snmp iptrans debug sccp public
|
||||
##
|
||||
## APP_LIB e.g. = msc vlr ssf hlr ae pps mnp smsc vms aas
|
||||
## LIB_ADD e.g. = -liba3a8 -lm
|
||||
|
||||
## OBJ_ADD = [Extend third party object files needed]
|
||||
## TEST_OBJ_PATH = [module object files Path for test ] => just for test
|
||||
##---------------------------------------------------------------------##
|
||||
|
||||
MODULE = tcp
|
||||
TYPE = plat
|
||||
|
||||
DBUG_FLAGS_ADD = -DDEBUG
|
||||
RELS_FLAGS_ADD =
|
||||
|
||||
##Default commonly as below
|
||||
|
||||
BUILD = lib
|
||||
CFG = debug
|
||||
|
||||
|
||||
PLT_LIB =
|
||||
|
||||
APP_LIB =
|
||||
LIB_ADD =
|
||||
|
||||
SRC_PATH = ./src
|
||||
INC_PATH = ./src/include
|
||||
PLT_PATH = ../../plat
|
||||
APP_PATH = ../../mss
|
||||
|
||||
OBJ_ADD =
|
||||
TEST_OBJ_PATH =
|
||||
|
||||
PREPROC_CMD =
|
||||
POSTPROC_CMD =
|
||||
|
||||
##---------------------------------------------------------------------##
|
||||
##--------------------------------------
|
||||
##
|
||||
## Make configuration(Customer define)
|
||||
##
|
||||
##--------------------------------------
|
||||
|
||||
## CCFLAG_SWITCH = on/off => gcc flag show on/off
|
||||
## COVER_NEED = yes/no => PTF cover report needed
|
||||
## COVER_REPORT_PATH = [path ] => PTF cover report path
|
||||
|
||||
CCFLAG_SWITCH = off
|
||||
COVER_NEED = no
|
||||
COVER_REPORT_PATH = ./output
|
||||
|
||||
##---------------------------------------------------------------------##
|
||||
|
||||
|
||||
##--------------------------------------
|
||||
##
|
||||
## include makefile.rules (Do not change)
|
||||
##
|
||||
##--------------------------------------
|
||||
include Makefile.rules
|
||||
32
proxy_c/tcp/src/include/tcp_if.h
Normal file
32
proxy_c/tcp/src/include/tcp_if.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef _TCP_IF_H_
|
||||
#define _TCP_IF_H_
|
||||
|
||||
#include "tcp_inc.h"
|
||||
#include "tcp_port.h"
|
||||
#define TCP_MAX_NUM_OF_SAP 4
|
||||
#define TCP_MAX_USER_NAME_LEN 16
|
||||
|
||||
typedef int (*tcp_recv_callback)(WORD usr_port, BYTE *pdata, WORD datalen);
|
||||
|
||||
typedef struct _tcp_sap_t
|
||||
{
|
||||
BYTE id;
|
||||
char name[TCP_MAX_USER_NAME_LEN];
|
||||
tcp_recv_callback recv_cb;
|
||||
}tcp_sap_t;
|
||||
|
||||
extern void tcp_init(void);
|
||||
extern void tcp_timer(void);
|
||||
extern int tcp_bind(tcp_sap_t *ptr_sap);
|
||||
extern int tcp_unbind(tcp_sap_t *ptr_sap, BYTE index);
|
||||
extern tcp_sap_t *tcp_sap_get_by_index(int index);
|
||||
|
||||
|
||||
//rtp_port.c
|
||||
extern int tcp_port_alloc_port(int sap_id, WORD usr_port, tcp_session_t *pSess);
|
||||
extern int tcp_port_release_port(int sap_id, WORD usr_port, WORD pid);
|
||||
extern int tcp_send(int sap_id, WORD usr_port, WORD pid, BYTE *payload, WORD len);
|
||||
extern tcp_session_t *tcp_port_update_sess(int sap_id, WORD usr_port, WORD pid, tcp_session_t *ptr_sess);
|
||||
|
||||
#endif
|
||||
|
||||
129
proxy_c/tcp/src/include/tcp_inc.h
Normal file
129
proxy_c/tcp/src/include/tcp_inc.h
Normal file
@@ -0,0 +1,129 @@
|
||||
#ifndef _TCP_INC_H_
|
||||
#define _TCP_INC_H_
|
||||
|
||||
//#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <math.h>
|
||||
#include <netdb.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
#include <termio.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/io.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <sys/sem.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
#ifndef _T_BYTE
|
||||
#define _T_BYTE
|
||||
typedef unsigned char BYTE;
|
||||
#endif
|
||||
|
||||
#ifndef _T_WORD
|
||||
#define _T_WORD
|
||||
typedef unsigned short WORD;
|
||||
#endif
|
||||
|
||||
#ifndef _T_DWORD
|
||||
#define _T_DWORD
|
||||
typedef unsigned long DWORD;
|
||||
#endif
|
||||
|
||||
#ifndef _T_ULL
|
||||
#define _T_ULL
|
||||
typedef unsigned long long ull;
|
||||
#endif
|
||||
|
||||
#ifndef _T_U8
|
||||
#define _T_U8
|
||||
typedef unsigned char u8;
|
||||
#endif
|
||||
|
||||
#ifndef _T_U16
|
||||
#define _T_U16
|
||||
typedef unsigned short u16;
|
||||
#endif
|
||||
|
||||
#ifndef _T_U32
|
||||
#define _T_U32
|
||||
typedef unsigned long u32;
|
||||
#endif
|
||||
|
||||
#ifndef _T_U64
|
||||
#define _T_U64
|
||||
typedef unsigned long long u64;
|
||||
#endif
|
||||
|
||||
#ifndef _T_BOOL
|
||||
#define _T_BOOL
|
||||
typedef int BOOL;
|
||||
#endif
|
||||
|
||||
#ifndef SUCCESS
|
||||
#define SUCCESS (0)
|
||||
#endif
|
||||
|
||||
#ifndef FAILURE
|
||||
#define FAILURE (-1)
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (1)
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE (0)
|
||||
#endif
|
||||
|
||||
#ifndef YES
|
||||
#define YES (1)
|
||||
#endif
|
||||
|
||||
#ifndef NO
|
||||
#define NO (0)
|
||||
#endif
|
||||
|
||||
#ifndef ERROR
|
||||
#define ERROR (-1)
|
||||
#endif
|
||||
|
||||
#ifndef EMPTY
|
||||
#define EMPTY (0)
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#define BUFSIZE 8192
|
||||
#define MAXBUFLEN 8192
|
||||
#define MAXLINE 8192
|
||||
|
||||
#endif
|
||||
|
||||
59
proxy_c/tcp/src/include/tcp_port.h
Normal file
59
proxy_c/tcp/src/include/tcp_port.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef _TCP_PORT_H_
|
||||
#define _TCP_PORT_H_
|
||||
|
||||
#include "tcp_inc.h"
|
||||
|
||||
#define TCP_MAX_NUM_OF_PORT 16
|
||||
#define TCP_MAX_RECV_MSG_LEN 1500
|
||||
#define TCP_MAX_SEND_MSG_LEN 1500
|
||||
#define TCP_MAX_PAYLOAD_SIZE 1350
|
||||
#define TCP_MAX_RECV_BUF_LEN 8192
|
||||
#define TCP_MAX_RECV_COUNT 4
|
||||
|
||||
typedef struct _tcp_header_t
|
||||
{
|
||||
BYTE ver; // version
|
||||
BYTE pt; // payload type
|
||||
WORD sn; // sequence number
|
||||
DWORD timestamp;
|
||||
DWORD ssrc; //synchronization src
|
||||
}tcp_header_t;
|
||||
|
||||
typedef struct _tcp_session_t
|
||||
{
|
||||
DWORD src_ip;
|
||||
WORD src_port;
|
||||
DWORD dst_ip;
|
||||
WORD dst_port;
|
||||
BYTE bServer; // tcp client: 0; server: 1;
|
||||
}tcp_session_t;
|
||||
|
||||
typedef struct _tcp_port_t
|
||||
{
|
||||
BYTE flag;
|
||||
int index;
|
||||
BYTE status;
|
||||
int timer;
|
||||
int retry_num;
|
||||
WORD usr_port;
|
||||
int fd;
|
||||
int cli_fd;
|
||||
|
||||
BYTE rv_buf[TCP_MAX_RECV_BUF_LEN];
|
||||
int buf_len;
|
||||
|
||||
int connected_num;
|
||||
int disconnect_num;
|
||||
int sent_fail_num;
|
||||
tcp_session_t sess;
|
||||
struct _tcp_sap_t *ptr_sap;
|
||||
}tcp_port_t;
|
||||
|
||||
extern void tcp_port_init(WORD id);
|
||||
extern void tcp_port_recv_msg(void);
|
||||
extern int tcp_link_fsm();
|
||||
|
||||
int get_tcp_sess(WORD hdlPort, tcp_session_t *sess);
|
||||
|
||||
#endif
|
||||
|
||||
95
proxy_c/tcp/src/tcp_if.c
Normal file
95
proxy_c/tcp/src/tcp_if.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
*
|
||||
*/
|
||||
#include "./include/tcp_if.h"
|
||||
#include "./include/tcp_port.h"
|
||||
|
||||
static tcp_sap_t tcp_sap[TCP_MAX_NUM_OF_SAP];
|
||||
|
||||
static void tcp_sap_init(tcp_sap_t *ptr_sap, BYTE index)
|
||||
{
|
||||
if((ptr_sap == NULL) || (index >= TCP_MAX_NUM_OF_SAP))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ptr_sap->id = index;
|
||||
strcpy(ptr_sap->name, "\0");
|
||||
ptr_sap->recv_cb = NULL;
|
||||
}
|
||||
|
||||
tcp_sap_t *tcp_sap_get_by_index(int index)
|
||||
{
|
||||
if(index < 0 || index >= TCP_MAX_NUM_OF_SAP)
|
||||
return NULL;
|
||||
return &tcp_sap[index];
|
||||
}
|
||||
|
||||
void tcp_init(void)
|
||||
{
|
||||
WORD i;
|
||||
|
||||
for(i = 0; i < TCP_MAX_NUM_OF_SAP; i++)
|
||||
{
|
||||
tcp_sap_init(&tcp_sap[i], (BYTE)i);
|
||||
}
|
||||
|
||||
for(i = 0; i < TCP_MAX_NUM_OF_PORT; i++)
|
||||
{
|
||||
tcp_port_init(i);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void tcp_timer(void)
|
||||
{
|
||||
tcp_link_fsm();
|
||||
tcp_port_recv_msg();
|
||||
}
|
||||
|
||||
int tcp_bind(tcp_sap_t *ptr_sap)
|
||||
{
|
||||
BYTE i;
|
||||
tcp_sap_t *ptr_tmp = NULL;
|
||||
|
||||
if((ptr_sap == NULL) || (ptr_sap->recv_cb == NULL))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(i = 0; i < TCP_MAX_NUM_OF_SAP; i++)
|
||||
{
|
||||
ptr_tmp = &tcp_sap[i];
|
||||
if(ptr_tmp->recv_cb != NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy((BYTE*)ptr_tmp, ptr_sap, sizeof(tcp_sap_t));
|
||||
ptr_tmp->id = i;
|
||||
ptr_tmp->name[TCP_MAX_USER_NAME_LEN-1] = '\0';
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tcp_unbind(tcp_sap_t *ptr_sap, BYTE index)
|
||||
{
|
||||
if((ptr_sap == NULL) || (index >= TCP_MAX_NUM_OF_SAP))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ptr_sap->id != index)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
tcp_sap_init(ptr_sap, index);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
867
proxy_c/tcp/src/tcp_port.c
Normal file
867
proxy_c/tcp/src/tcp_port.c
Normal file
@@ -0,0 +1,867 @@
|
||||
/*
|
||||
* tcp port
|
||||
*/
|
||||
#include "./include/tcp_port.h"
|
||||
#include "./include/tcp_if.h"
|
||||
|
||||
#define TCP_F_BB1 0x7E // Begin: The first byte
|
||||
#define TCP_F_BB2 0xA5 // Begin: The second byte
|
||||
#define TCP_F_EB1 0x7E // End: The first byte
|
||||
#define TCP_F_EB2 0x0D // End: The second byte
|
||||
|
||||
#define TCP_F_INF_BEGIN_FLAG_LEN 2 // length of begin flag
|
||||
#define TCP_F_INF_MSG_LEN_LEN 2 // length of msg length field
|
||||
//#define TCP_F_INF_MSG_TYPE_LEN 2 // length of msg type
|
||||
#define TCP_F_INF_END_FLAG_LEN 2 // length of end flag
|
||||
#define TCP_F_INF_HEAD_LEN 4 // length of format begin+lengthField
|
||||
#define TCP_F_INF_ALL_LEN 6 // total length of format
|
||||
|
||||
#define TCP_IsfBegin(f1,f2) ((f1==TCP_F_BB1) && (f2==TCP_F_BB2))// Begin flag of msg
|
||||
#define TCP_IsfEnd(f1,f2) ((f1==TCP_F_EB1) && (f2==TCP_F_EB2))// End flag of msg
|
||||
|
||||
#define TCP_MSG_DATA 1 // Data
|
||||
#define TCP_MSG_HB 2 // HB
|
||||
#define TCP_MSG_HB_ACK 3 // HB_ACK
|
||||
|
||||
#define TCP_TIMER_1_SEC (100) // 10ms * 100
|
||||
#define TCP_TIMER_WAIT_CONNECT (5) // 50ms
|
||||
#define TCP_TIMER_REINIT (3*TCP_TIMER_1_SEC) // 3 Sec
|
||||
#define TCP_TIMER_RECONNECT (3*TCP_TIMER_1_SEC) // 3 Sec
|
||||
#define TCP_TIMER_HB (3*TCP_TIMER_1_SEC) // 3 Sec
|
||||
|
||||
#define TCP_MAX_RETRY_NUM (3)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TCP_STATUS_NULL,
|
||||
TCP_STATUS_INITING,
|
||||
TCP_STATUS_INITED,
|
||||
TCP_STATUS_CONNECTING,
|
||||
TCP_STATUS_TESTING,
|
||||
TCP_STATUS_CONNECTED,
|
||||
TCP_STATUS_MAX,
|
||||
}e_tcp_status;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WORD usMsgId; // Tcp internal message Id, 1: Data; 2: HB; 3: HB_ACK
|
||||
WORD usPlLen; // Payload length
|
||||
DWORD param1; // App param1, optional
|
||||
DWORD param2; // App param2, optional
|
||||
DWORD param3; // App param3, optional
|
||||
} tcp_head_t;
|
||||
|
||||
static char tcp_status_str[TCP_STATUS_MAX][64] = {\
|
||||
"null", \
|
||||
"initing", \
|
||||
"inited", \
|
||||
"connecting", \
|
||||
"testing", \
|
||||
"connected"
|
||||
};
|
||||
|
||||
static tcp_port_t tcp_port[TCP_MAX_NUM_OF_PORT];
|
||||
|
||||
void tcp_port_init(WORD id)
|
||||
{
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
|
||||
if(id >= TCP_MAX_NUM_OF_PORT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ptr_port = &tcp_port[id];
|
||||
memset((BYTE*)ptr_port, 0, sizeof(tcp_port_t));
|
||||
ptr_port->fd = -1;
|
||||
ptr_port->cli_fd = -1;
|
||||
ptr_port->ptr_sap = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
long tcp_str_to_uip(char *src_ip)
|
||||
{
|
||||
return inet_addr(src_ip);
|
||||
}
|
||||
|
||||
static tcp_port_t *tcp_port_get_by_index(WORD index)
|
||||
{
|
||||
if (index >= TCP_MAX_NUM_OF_PORT)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &tcp_port[index];
|
||||
}
|
||||
|
||||
|
||||
static int tcp_port_get_unused_pid(void)
|
||||
{
|
||||
static WORD index = 0;
|
||||
WORD id, i;
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
|
||||
i = index;
|
||||
do
|
||||
{
|
||||
id = i;
|
||||
ptr_port = &tcp_port[id];
|
||||
if(++i >= TCP_MAX_NUM_OF_PORT)
|
||||
{
|
||||
i = 0;
|
||||
}
|
||||
|
||||
if(ptr_port->flag != FALSE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
index = i;
|
||||
return id;
|
||||
}while(i != index);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int tcp_init_socket(tcp_session_t *pSess)
|
||||
{
|
||||
int sock = -1, on = 1, timeout = 20;
|
||||
struct sockaddr_in srcaddr;
|
||||
|
||||
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
|
||||
{
|
||||
close(sock);
|
||||
return -2;
|
||||
}
|
||||
|
||||
//if (bServer)
|
||||
{
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &timeout, sizeof(timeout)) != 0)
|
||||
{
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
|
||||
if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0)
|
||||
{
|
||||
close(sock);
|
||||
return -4;
|
||||
}
|
||||
|
||||
memset( (void *)&srcaddr, 0, sizeof(srcaddr) );
|
||||
srcaddr.sin_family = AF_INET;
|
||||
srcaddr.sin_addr.s_addr = pSess->src_ip;//htonl( INADDR_ANY );
|
||||
srcaddr.sin_port = htons(pSess->src_port);
|
||||
if (bind(sock, (struct sockaddr *)&srcaddr, sizeof(srcaddr)) < 0)
|
||||
{
|
||||
close(sock);
|
||||
return -5;
|
||||
}
|
||||
|
||||
if (pSess->bServer)
|
||||
{
|
||||
// change to passive socket
|
||||
if (listen(sock, 5))
|
||||
{
|
||||
close(sock);
|
||||
return -6;
|
||||
}
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
|
||||
static int tcp_set_status(tcp_port_t *ptr_port, WORD new_status)
|
||||
{
|
||||
if ((ptr_port == NULL) || (ptr_port->status == new_status) || (new_status >= TCP_STATUS_MAX))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (ptr_port->status == TCP_STATUS_CONNECTED)
|
||||
{
|
||||
ptr_port->disconnect_num++;
|
||||
}
|
||||
|
||||
ptr_port->status = new_status;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int tcp_connect(tcp_port_t *ptr_port)
|
||||
{
|
||||
int ret;
|
||||
struct sockaddr_in serv_addr;
|
||||
|
||||
if (ptr_port == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* set family to internet */
|
||||
bzero((char *) &serv_addr, sizeof(serv_addr));
|
||||
serv_addr.sin_family = AF_INET;
|
||||
serv_addr.sin_addr.s_addr = ptr_port->sess.dst_ip;
|
||||
serv_addr.sin_port = htons(ptr_port->sess.dst_port);
|
||||
ret = connect(ptr_port->fd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr));
|
||||
if (ret < 0)
|
||||
{
|
||||
if (errno == EINPROGRESS)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*if((106 == errno)//Transport endpoint is already connected
|
||||
||(89 == errno))//Destination address required
|
||||
{
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int tcp_check_conn(tcp_port_t *ptr_port)
|
||||
{
|
||||
int client_sock;
|
||||
int timeout = 20;
|
||||
struct sockaddr_in remote;
|
||||
socklen_t len = sizeof(struct sockaddr_in);
|
||||
tcp_session_t *pSess = NULL;
|
||||
|
||||
if (ptr_port == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
pSess = &ptr_port->sess;
|
||||
|
||||
// fill with zero terms
|
||||
memset(&remote, 0, sizeof( remote));
|
||||
|
||||
// wait for connetion
|
||||
client_sock = accept(ptr_port->fd, (struct sockaddr *)&(remote), &len);
|
||||
if ( client_sock < 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((remote.sin_port != htons(pSess->dst_port)) || (remote.sin_addr.s_addr != pSess->dst_ip))
|
||||
{
|
||||
close(client_sock);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (setsockopt(client_sock, SOL_SOCKET, SO_KEEPALIVE, &timeout, sizeof(timeout)) != 0)
|
||||
{
|
||||
//return -3;
|
||||
}
|
||||
|
||||
if (fcntl(client_sock, F_SETFL, O_NONBLOCK) < 0)
|
||||
{
|
||||
//return -4;
|
||||
}
|
||||
|
||||
ptr_port->cli_fd = client_sock;
|
||||
return client_sock;
|
||||
}
|
||||
|
||||
|
||||
int tcp_port_alloc_port(int sap_id, WORD usr_port, tcp_session_t *pSess)
|
||||
{
|
||||
int pid;
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
tcp_sap_t *ptr_sap = NULL;
|
||||
|
||||
if(pSess == NULL || pSess->src_ip == 0 || pSess->src_port == 0 \
|
||||
|| pSess->dst_ip == 0 || pSess->dst_port == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((ptr_sap = tcp_sap_get_by_index(sap_id)) == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((pid = tcp_port_get_unused_pid()) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr_port = &tcp_port[pid];
|
||||
if((ptr_port->fd = tcp_init_socket(pSess)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr_port->flag = TRUE;
|
||||
ptr_port->index = pid;
|
||||
tcp_set_status(ptr_port, TCP_STATUS_INITED);
|
||||
ptr_port->timer = 5;
|
||||
ptr_port->retry_num = 0;
|
||||
ptr_port->ptr_sap = ptr_sap;
|
||||
ptr_port->usr_port = usr_port;
|
||||
ptr_port->cli_fd = -1;
|
||||
ptr_port->buf_len = 0;
|
||||
|
||||
ptr_port->connected_num = 0;
|
||||
ptr_port->disconnect_num = 0;
|
||||
ptr_port->sent_fail_num = 0;
|
||||
|
||||
memcpy(&ptr_port->sess, pSess, sizeof(tcp_session_t));
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
|
||||
int tcp_port_release_port(int sap_id, WORD usr_port, WORD pid)
|
||||
{
|
||||
tcp_sap_t *ptr_sap = NULL;
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
|
||||
if((ptr_sap = tcp_sap_get_by_index(sap_id)) == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((ptr_port = tcp_port_get_by_index(pid)) == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((ptr_port->ptr_sap != ptr_sap) || (ptr_port->usr_port != usr_port))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ptr_port->fd >= 0)
|
||||
{
|
||||
close(ptr_port->fd);
|
||||
}
|
||||
|
||||
tcp_port_init(pid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
tcp_session_t *tcp_port_update_sess(int sap_id, WORD usr_port, WORD pid, tcp_session_t *ptr_sess)
|
||||
{
|
||||
tcp_sap_t *ptr_sap = NULL;
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
|
||||
if(ptr_sess == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((ptr_sap = tcp_sap_get_by_index(sap_id)) == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((ptr_port = tcp_port_get_by_index(pid)) == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((ptr_port->ptr_sap != ptr_sap) || (ptr_port->usr_port != usr_port))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy((BYTE*)&ptr_port->sess, (BYTE*)ptr_sess, sizeof(tcp_session_t));
|
||||
|
||||
return &ptr_port->sess;
|
||||
}
|
||||
|
||||
|
||||
int get_tcp_sess(WORD pid, tcp_session_t *sess)
|
||||
{
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
|
||||
if (pid >= TCP_MAX_NUM_OF_PORT)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(sess == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((ptr_port = tcp_port_get_by_index(pid)) == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(sess, &ptr_port->sess, sizeof(tcp_session_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int tcp_send_msg(tcp_port_t *ptr_port, BYTE *msg, WORD len)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if((ptr_port == NULL) || (len > TCP_MAX_SEND_MSG_LEN))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ptr_port->sess.bServer)
|
||||
{
|
||||
fd = ptr_port->cli_fd;
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = ptr_port->fd;
|
||||
}
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (send(fd, msg, len, MSG_NOSIGNAL) < 0)// add MSG_NOSIGNAL, to avoid Broken pipe, while sending data after received FIN and sent FIN_ACK
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int tcp_send_hb(tcp_port_t *ptr_port, WORD msg_id)
|
||||
{
|
||||
int ret = -1;
|
||||
BYTE msg_buf[TCP_MAX_SEND_MSG_LEN];
|
||||
WORD msg_len;
|
||||
DWORD pos = 0;
|
||||
BYTE *pDst = NULL;
|
||||
tcp_head_t *pHead = NULL;
|
||||
|
||||
if(ptr_port == NULL || ptr_port->flag == FALSE)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
pDst = msg_buf;
|
||||
|
||||
// Begin flag
|
||||
pDst[pos++] = TCP_F_BB1;
|
||||
pDst[pos++] = TCP_F_BB2;
|
||||
//
|
||||
|
||||
// len, 2 Bytes
|
||||
msg_len = htons(sizeof(tcp_head_t));
|
||||
memcpy(&pDst[pos], (BYTE *)&msg_len, sizeof(msg_len));
|
||||
pos += sizeof(msg_len);
|
||||
//
|
||||
|
||||
// Head
|
||||
pHead = (tcp_head_t *)&pDst[pos];
|
||||
pHead->usMsgId = htons(msg_id);
|
||||
pHead->usPlLen = 0;
|
||||
pHead->param1 = 0;
|
||||
pHead->param2 = 0;
|
||||
pHead->param3 = 0;
|
||||
memcpy(&pDst[pos], (BYTE *)pHead, sizeof(tcp_head_t));
|
||||
pos += sizeof(tcp_head_t);
|
||||
//
|
||||
|
||||
// flagEnd
|
||||
pDst[pos++] = TCP_F_EB1;
|
||||
pDst[pos++] = TCP_F_EB2;
|
||||
//
|
||||
|
||||
msg_len = pos;
|
||||
|
||||
ret = tcp_send_msg(ptr_port, msg_buf, msg_len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int tcp_handle_hb(tcp_port_t *ptr_port, tcp_head_t *pTcpHead)
|
||||
{
|
||||
WORD usMsgId = 0;
|
||||
if (ptr_port == NULL || pTcpHead == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pTcpHead->usPlLen != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
usMsgId = ntohs(pTcpHead->usMsgId);
|
||||
if (usMsgId == TCP_MSG_HB)
|
||||
{
|
||||
tcp_send_hb(ptr_port, TCP_MSG_HB_ACK);
|
||||
}
|
||||
else if (usMsgId == TCP_MSG_HB_ACK)
|
||||
{
|
||||
if (ptr_port->status == TCP_STATUS_TESTING)
|
||||
{
|
||||
tcp_set_status(ptr_port, TCP_STATUS_CONNECTED);
|
||||
ptr_port->connected_num++;
|
||||
ptr_port->retry_num = 0;
|
||||
}
|
||||
else if (ptr_port->status == TCP_STATUS_CONNECTED)
|
||||
{
|
||||
ptr_port->retry_num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//static int tcp_port_handle_recv_msg(WORD pid, BYTE *buf, WORD len)
|
||||
static int tcp_port_handle_recv_msg(tcp_port_t *ptr_port)
|
||||
{
|
||||
tcp_sap_t *ptr_sap = NULL;
|
||||
|
||||
if(ptr_port == NULL || ptr_port->ptr_sap == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr_sap = ptr_port->ptr_sap;
|
||||
if(ptr_sap->recv_cb == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr_sap->recv_cb(ptr_port->usr_port, ptr_port->rv_buf, ptr_port->buf_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tcp_port_recv_msg(void)
|
||||
{
|
||||
int index, i, len, addr_len, fd, pos;
|
||||
BYTE msg_buf[TCP_MAX_RECV_MSG_LEN];
|
||||
//struct timeval tv;
|
||||
|
||||
struct sockaddr_in sin_addr;
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
|
||||
addr_len = sizeof(struct sockaddr);
|
||||
memset(&sin_addr, 0, addr_len);
|
||||
|
||||
for(index = 0; index < TCP_MAX_NUM_OF_PORT; index++)
|
||||
{
|
||||
ptr_port = &tcp_port[index];
|
||||
if(ptr_port->flag == FALSE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(((ptr_port->sess.bServer) && (ptr_port->fd < 0 || ptr_port->cli_fd < 0)) \
|
||||
|| ((!ptr_port->sess.bServer) && (ptr_port->fd < 0)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ptr_port->sess.bServer)
|
||||
{
|
||||
fd = ptr_port->cli_fd;
|
||||
}
|
||||
else
|
||||
{
|
||||
fd = ptr_port->fd;
|
||||
}
|
||||
|
||||
for(i = 0; i < TCP_MAX_RECV_COUNT; i++)
|
||||
{
|
||||
pos = ptr_port->buf_len;
|
||||
len = recv(fd, msg_buf, TCP_MAX_RECV_MSG_LEN, 0);
|
||||
if(len <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if((pos + len) >= TCP_MAX_RECV_BUF_LEN)
|
||||
{
|
||||
ptr_port->buf_len = 0;
|
||||
pos = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(&ptr_port->rv_buf[pos], msg_buf, len);
|
||||
ptr_port->buf_len += len;
|
||||
tcp_port_handle_recv_msg(ptr_port);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int tcp_send(int sap_id, WORD usr_port, WORD pid, BYTE *payload, WORD len)
|
||||
{
|
||||
int ret = -1;
|
||||
BYTE msg_buf[TCP_MAX_SEND_MSG_LEN];
|
||||
WORD msg_len;
|
||||
tcp_sap_t *ptr_sap = NULL;
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
WORD pos = 0;
|
||||
BYTE *pDst = NULL;
|
||||
|
||||
if((payload == NULL) || (len > TCP_MAX_PAYLOAD_SIZE))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((ptr_sap = tcp_sap_get_by_index(sap_id)) == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(pid >= TCP_MAX_NUM_OF_PORT)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr_port = &tcp_port[pid];
|
||||
if((ptr_port->flag == FALSE) || (ptr_port->ptr_sap != ptr_sap) || (ptr_port->usr_port != usr_port))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
if (ptr_port->status != TCP_STATUS_CONNECTED)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
pDst = msg_buf;
|
||||
|
||||
memcpy(&pDst[pos], payload, len);
|
||||
pos += len;
|
||||
|
||||
msg_len = pos;
|
||||
|
||||
ret = tcp_send_msg(ptr_port, msg_buf, msg_len);
|
||||
if(ret < 0)
|
||||
{
|
||||
ptr_port->sent_fail_num++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int tcp_link_fsm()
|
||||
{
|
||||
int i;
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
tcp_session_t *pSess = NULL;
|
||||
|
||||
for (i=0; i<TCP_MAX_NUM_OF_PORT; i++)
|
||||
{
|
||||
ptr_port = &tcp_port[i];
|
||||
|
||||
if (!ptr_port->flag)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//if (ptr_port->fd < 0)
|
||||
//{
|
||||
// tcp_port_init(i);
|
||||
// continue;
|
||||
//}
|
||||
|
||||
pSess = &ptr_port->sess;
|
||||
switch (ptr_port->status)
|
||||
{
|
||||
case TCP_STATUS_INITING:
|
||||
if (--ptr_port->timer > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ptr_port->fd = tcp_init_socket(pSess);
|
||||
if (ptr_port->fd < 0)
|
||||
{
|
||||
ptr_port->timer = TCP_TIMER_REINIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
tcp_set_status(ptr_port, TCP_STATUS_INITED);
|
||||
}
|
||||
break;
|
||||
case TCP_STATUS_INITED:
|
||||
if (--ptr_port->timer > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pSess->bServer)
|
||||
{
|
||||
if (tcp_check_conn(ptr_port) < 0)
|
||||
{
|
||||
ptr_port->timer = TCP_TIMER_WAIT_CONNECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr_port->timer = 0;
|
||||
ptr_port->retry_num = 0;
|
||||
tcp_set_status(ptr_port, TCP_STATUS_TESTING);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tcp_connect(ptr_port) < 0)
|
||||
{
|
||||
close(ptr_port->fd);
|
||||
ptr_port->fd = -1;
|
||||
tcp_set_status(ptr_port, TCP_STATUS_INITING);
|
||||
ptr_port->timer = TCP_TIMER_REINIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr_port->timer = TCP_TIMER_WAIT_CONNECT;
|
||||
ptr_port->retry_num = 0;
|
||||
tcp_set_status(ptr_port, TCP_STATUS_TESTING);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TCP_STATUS_TESTING:// sending HB
|
||||
case TCP_STATUS_CONNECTED:
|
||||
break;
|
||||
if (--ptr_port->timer > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ptr_port->retry_num++ >= TCP_MAX_RETRY_NUM)
|
||||
{
|
||||
if (ptr_port->sess.bServer)
|
||||
{
|
||||
close(ptr_port->cli_fd);
|
||||
ptr_port->cli_fd = -1;
|
||||
ptr_port->timer = 0;
|
||||
tcp_set_status(ptr_port, TCP_STATUS_INITED);
|
||||
}
|
||||
else
|
||||
{
|
||||
close(ptr_port->fd);
|
||||
ptr_port->fd = -1;
|
||||
ptr_port->timer = 0;
|
||||
tcp_set_status(ptr_port, TCP_STATUS_INITING);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//tcp_send_hb(ptr_port, TCP_MSG_HB);
|
||||
ptr_port->timer = TCP_TIMER_HB;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BOOL tcp_print_all_port(void)
|
||||
{
|
||||
int j = 0, i;
|
||||
char buf[516], tmp_buf[8];
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
|
||||
strcpy(buf, "\0");
|
||||
for(i = 0; i < TCP_MAX_NUM_OF_PORT; i++)
|
||||
{
|
||||
ptr_port = &tcp_port[i];
|
||||
if(ptr_port->flag == TRUE)
|
||||
{
|
||||
if(j % 20 == 0 && j != 0)
|
||||
{
|
||||
strcpy(buf, "\0");
|
||||
}
|
||||
sprintf(tmp_buf, "%d ", i);
|
||||
strcat(buf, tmp_buf);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
if(j % 20)
|
||||
{
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL tcp_print_port(int pid)
|
||||
{
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
|
||||
if((pid < 0) || (pid >= TCP_MAX_NUM_OF_PORT))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ptr_port = &tcp_port[pid];
|
||||
if(ptr_port->flag == FALSE)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (ptr_port->status < TCP_STATUS_MAX)
|
||||
{
|
||||
}
|
||||
if (ptr_port->sess.bServer)
|
||||
{
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL tcp_clear_stat(int pid)
|
||||
{
|
||||
tcp_port_t *ptr_port = NULL;
|
||||
|
||||
if((pid < 0) || (pid >= TCP_MAX_NUM_OF_PORT))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ptr_port = &tcp_port[pid];
|
||||
if(ptr_port->flag == FALSE)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
ptr_port->connected_num = 0;
|
||||
ptr_port->disconnect_num = 0;
|
||||
ptr_port->sent_fail_num = 0;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
5
proxy_c/third-lib/ReadME.txt
Normal file
5
proxy_c/third-lib/ReadME.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
libevent-c
|
||||
http://libevent.org
|
||||
libevent-2.1.8-stable.tar.gz
|
||||
|
||||
|
||||
BIN
proxy_c/third-lib/curl-7.52.1.tar.gz
Normal file
BIN
proxy_c/third-lib/curl-7.52.1.tar.gz
Normal file
Binary file not shown.
44
proxy_c/third-lib/json-c/Makefile
Normal file
44
proxy_c/third-lib/json-c/Makefile
Normal file
@@ -0,0 +1,44 @@
|
||||
release = no
|
||||
cover = no
|
||||
CC = gcc
|
||||
CPP = g++
|
||||
LD = ld
|
||||
AR = ar
|
||||
CP = cp
|
||||
|
||||
ifeq ($(release), no)
|
||||
CFLAGS += -Wall -Werror -g -fPIC
|
||||
else
|
||||
CFLAGS += -Wall -Werror -O3 -fPIC
|
||||
endif
|
||||
|
||||
LIB_DIR = ./lib
|
||||
CSRC_DIR = ./src
|
||||
OBJ_DIR = ./obj
|
||||
|
||||
CSRCS = $(wildcard $(CSRC_DIR)/*.c)
|
||||
COBJS := $(patsubst %.c, $(OBJ_DIR)/%.o, $(notdir $(CSRCS)))
|
||||
|
||||
TARGET_LIB = $(OBJ_DIR)/libjson.a
|
||||
|
||||
all : chkobjdir $(TARGET_LIB)
|
||||
|
||||
chkobjdir:
|
||||
@if test ! -d $(OBJ_DIR); \
|
||||
then \
|
||||
mkdir $(OBJ_DIR);\
|
||||
fi
|
||||
|
||||
$(OBJ_DIR)/%.o : $(CSRC_DIR)/%.c
|
||||
@echo "COMPILE $<"
|
||||
@$(CC) -fPIC $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(TARGET_LIB) : $(COBJS)
|
||||
@echo "AR $(TARGET_LIB)"
|
||||
@$(AR) cr $(TARGET_LIB) $(COBJS)
|
||||
@$(CP) $(TARGET_LIB) $(LIB_DIR)
|
||||
|
||||
.PHONY:clean
|
||||
clean:
|
||||
@echo "CLEAN $(TARGET_LIB)"
|
||||
@rm -rf $(TARGET_LIB) $(OBJ_DIR)
|
||||
70
proxy_c/third-lib/json-c/include/json-c/arraylist.h
Normal file
70
proxy_c/third-lib/json-c/include/json-c/arraylist.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* $Id: arraylist.h,v 1.4 2006/01/26 02:16:28 mclark Exp $
|
||||
*
|
||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||
* Michael Clark <michael@metaparadigm.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Internal methods for working with json_type_array objects.
|
||||
* Although this is exposed by the json_object_get_array() method,
|
||||
* it is not recommended for direct use.
|
||||
*/
|
||||
#ifndef _arraylist_h_
|
||||
#define _arraylist_h_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ARRAY_LIST_DEFAULT_SIZE 32
|
||||
|
||||
typedef void (array_list_free_fn) (void *data);
|
||||
|
||||
struct array_list
|
||||
{
|
||||
void **array;
|
||||
size_t length;
|
||||
size_t size;
|
||||
array_list_free_fn *free_fn;
|
||||
};
|
||||
typedef struct array_list array_list;
|
||||
|
||||
extern struct array_list*
|
||||
array_list_new(array_list_free_fn *free_fn);
|
||||
|
||||
extern void
|
||||
array_list_free(struct array_list *al);
|
||||
|
||||
extern void*
|
||||
array_list_get_idx(struct array_list *al, size_t i);
|
||||
|
||||
extern int
|
||||
array_list_put_idx(struct array_list *al, size_t i, void *data);
|
||||
|
||||
extern int
|
||||
array_list_add(struct array_list *al, void *data);
|
||||
|
||||
extern size_t
|
||||
array_list_length(struct array_list *al);
|
||||
|
||||
extern void
|
||||
array_list_sort(struct array_list *arr, int(*compar)(const void *, const void *));
|
||||
|
||||
extern void* array_list_bsearch(const void **key,
|
||||
struct array_list *arr,
|
||||
int (*sort_fn)(const void *, const void *));
|
||||
|
||||
extern int
|
||||
array_list_del_idx(struct array_list *arr, size_t idx, size_t count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
42
proxy_c/third-lib/json-c/include/json-c/json.h
Normal file
42
proxy_c/third-lib/json-c/include/json-c/json.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* $Id: json.h,v 1.6 2006/01/26 02:16:28 mclark Exp $
|
||||
*
|
||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||
* Michael Clark <michael@metaparadigm.com>
|
||||
* Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief A convenience header that may be included instead of other individual ones.
|
||||
*/
|
||||
#ifndef _json_h_
|
||||
#define _json_h_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* BEGIN lihua 2018-07-11 PN: 屏蔽此行 */
|
||||
#if 0
|
||||
#include "debug.h"
|
||||
#endif
|
||||
/* BEGIN lihua 2018-07-11 */
|
||||
#include "linkhash.h"
|
||||
#include "arraylist.h"
|
||||
#include "json_util.h"
|
||||
#include "json_object.h"
|
||||
#include "json_pointer.h"
|
||||
#include "json_tokener.h"
|
||||
#include "json_object_iterator.h"
|
||||
#include "json_c_version.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
40
proxy_c/third-lib/json-c/include/json-c/json_c_version.h
Normal file
40
proxy_c/third-lib/json-c/include/json-c/json_c_version.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2012,2017 Eric Haszlakiewicz
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Methods for retrieving the json-c version.
|
||||
*/
|
||||
#ifndef _json_c_version_h_
|
||||
#define _json_c_version_h_
|
||||
|
||||
#define JSON_C_MAJOR_VERSION 0
|
||||
#define JSON_C_MINOR_VERSION 13
|
||||
#define JSON_C_MICRO_VERSION 99
|
||||
#define JSON_C_VERSION_NUM ((JSON_C_MAJOR_VERSION << 16) | \
|
||||
(JSON_C_MINOR_VERSION << 8) | \
|
||||
JSON_C_MICRO_VERSION)
|
||||
#define JSON_C_VERSION "0.13.99"
|
||||
|
||||
/**
|
||||
* @see JSON_C_VERSION
|
||||
* @return the version of the json-c library as a string
|
||||
*/
|
||||
const char *json_c_version(void); /* Returns JSON_C_VERSION */
|
||||
|
||||
/**
|
||||
* The json-c version encoded into an int, with the low order 8 bits
|
||||
* being the micro version, the next higher 8 bits being the minor version
|
||||
* and the next higher 8 bits being the major version.
|
||||
* For example, 7.12.99 would be 0x00070B63.
|
||||
*
|
||||
* @see JSON_C_VERSION_NUM
|
||||
* @return the version of the json-c library as an int
|
||||
*/
|
||||
int json_c_version_num(void); /* Returns JSON_C_VERSION_NUM */
|
||||
|
||||
#endif
|
||||
4
proxy_c/third-lib/json-c/include/json-c/json_config.h
Normal file
4
proxy_c/third-lib/json-c/include/json-c/json_config.h
Normal file
@@ -0,0 +1,4 @@
|
||||
/* json_config.h. Generated from json_config.h.in by configure. */
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define JSON_C_HAVE_INTTYPES_H 1
|
||||
23
proxy_c/third-lib/json-c/include/json-c/json_inttypes.h
Normal file
23
proxy_c/third-lib/json-c/include/json-c/json_inttypes.h
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Do not use, json-c internal, may be changed or removed at any time.
|
||||
*/
|
||||
#ifndef _json_inttypes_h_
|
||||
#define _json_inttypes_h_
|
||||
|
||||
#include "json_config.h"
|
||||
|
||||
#ifdef JSON_C_HAVE_INTTYPES_H
|
||||
/* inttypes.h includes stdint.h */
|
||||
#include <inttypes.h>
|
||||
|
||||
#else
|
||||
#include <stdint.h>
|
||||
|
||||
#define PRId64 "I64d"
|
||||
#define SCNd64 "I64d"
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1028
proxy_c/third-lib/json-c/include/json-c/json_object.h
Normal file
1028
proxy_c/third-lib/json-c/include/json-c/json_object.h
Normal file
File diff suppressed because it is too large
Load Diff
240
proxy_c/third-lib/json-c/include/json-c/json_object_iterator.h
Normal file
240
proxy_c/third-lib/json-c/include/json-c/json_object_iterator.h
Normal file
@@ -0,0 +1,240 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file json_object_iterator.h
|
||||
*
|
||||
* Copyright (c) 2009-2012 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
* @brief An API for iterating over json_type_object objects,
|
||||
* styled to be familiar to C++ programmers.
|
||||
* Unlike json_object_object_foreach() and
|
||||
* json_object_object_foreachC(), this avoids the need to expose
|
||||
* json-c internals like lh_entry.
|
||||
*
|
||||
* API attributes: <br>
|
||||
* * Thread-safe: NO<br>
|
||||
* * Reentrant: NO
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef JSON_OBJECT_ITERATOR_H
|
||||
#define JSON_OBJECT_ITERATOR_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Forward declaration for the opaque iterator information.
|
||||
*/
|
||||
struct json_object_iter_info_;
|
||||
|
||||
/**
|
||||
* The opaque iterator that references a name/value pair within
|
||||
* a JSON Object instance or the "end" iterator value.
|
||||
*/
|
||||
struct json_object_iterator {
|
||||
const void* opaque_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* forward declaration of json-c's JSON value instance structure
|
||||
*/
|
||||
struct json_object;
|
||||
|
||||
|
||||
/**
|
||||
* Initializes an iterator structure to a "default" value that
|
||||
* is convenient for initializing an iterator variable to a
|
||||
* default state (e.g., initialization list in a class'
|
||||
* constructor).
|
||||
*
|
||||
* @code
|
||||
* struct json_object_iterator iter = json_object_iter_init_default();
|
||||
* MyClass() : iter_(json_object_iter_init_default())
|
||||
* @endcode
|
||||
*
|
||||
* @note The initialized value doesn't reference any specific
|
||||
* pair, is considered an invalid iterator, and MUST NOT
|
||||
* be passed to any json-c API that expects a valid
|
||||
* iterator.
|
||||
*
|
||||
* @note User and internal code MUST NOT make any assumptions
|
||||
* about and dependencies on the value of the "default"
|
||||
* iterator value.
|
||||
*
|
||||
* @return json_object_iterator
|
||||
*/
|
||||
struct json_object_iterator
|
||||
json_object_iter_init_default(void);
|
||||
|
||||
/** Retrieves an iterator to the first pair of the JSON Object.
|
||||
*
|
||||
* @warning Any modification of the underlying pair invalidates all
|
||||
* iterators to that pair.
|
||||
*
|
||||
* @param obj JSON Object instance (MUST be of type json_object)
|
||||
*
|
||||
* @return json_object_iterator If the JSON Object has at
|
||||
* least one pair, on return, the iterator refers
|
||||
* to the first pair. If the JSON Object doesn't
|
||||
* have any pairs, the returned iterator is
|
||||
* equivalent to the "end" iterator for the same
|
||||
* JSON Object instance.
|
||||
*
|
||||
* @code
|
||||
* struct json_object_iterator it;
|
||||
* struct json_object_iterator itEnd;
|
||||
* struct json_object* obj;
|
||||
*
|
||||
* obj = json_tokener_parse("{'first':'george', 'age':100}");
|
||||
* it = json_object_iter_begin(obj);
|
||||
* itEnd = json_object_iter_end(obj);
|
||||
*
|
||||
* while (!json_object_iter_equal(&it, &itEnd)) {
|
||||
* printf("%s\n",
|
||||
* json_object_iter_peek_name(&it));
|
||||
* json_object_iter_next(&it);
|
||||
* }
|
||||
*
|
||||
* @endcode
|
||||
*/
|
||||
struct json_object_iterator
|
||||
json_object_iter_begin(struct json_object* obj);
|
||||
|
||||
/** Retrieves the iterator that represents the position beyond the
|
||||
* last pair of the given JSON Object instance.
|
||||
*
|
||||
* @warning Do NOT write code that assumes that the "end"
|
||||
* iterator value is NULL, even if it is so in a
|
||||
* particular instance of the implementation.
|
||||
*
|
||||
* @note The reason we do not (and MUST NOT) provide
|
||||
* "json_object_iter_is_end(json_object_iterator* iter)"
|
||||
* type of API is because it would limit the underlying
|
||||
* representation of name/value containment (or force us
|
||||
* to add additional, otherwise unnecessary, fields to
|
||||
* the iterator structure). The "end" iterator and the
|
||||
* equality test method, on the other hand, permit us to
|
||||
* cleanly abstract pretty much any reasonable underlying
|
||||
* representation without burdening the iterator
|
||||
* structure with unnecessary data.
|
||||
*
|
||||
* @note For performance reasons, memorize the "end" iterator prior
|
||||
* to any loop.
|
||||
*
|
||||
* @param obj JSON Object instance (MUST be of type json_object)
|
||||
*
|
||||
* @return json_object_iterator On return, the iterator refers
|
||||
* to the "end" of the Object instance's pairs
|
||||
* (i.e., NOT the last pair, but "beyond the last
|
||||
* pair" value)
|
||||
*/
|
||||
struct json_object_iterator
|
||||
json_object_iter_end(const struct json_object* obj);
|
||||
|
||||
/** Returns an iterator to the next pair, if any
|
||||
*
|
||||
* @warning Any modification of the underlying pair
|
||||
* invalidates all iterators to that pair.
|
||||
*
|
||||
* @param iter [IN/OUT] Pointer to iterator that references a
|
||||
* name/value pair; MUST be a valid, non-end iterator.
|
||||
* WARNING: bad things will happen if invalid or "end"
|
||||
* iterator is passed. Upon return will contain the
|
||||
* reference to the next pair if there is one; if there
|
||||
* are no more pairs, will contain the "end" iterator
|
||||
* value, which may be compared against the return value
|
||||
* of json_object_iter_end() for the same JSON Object
|
||||
* instance.
|
||||
*/
|
||||
void
|
||||
json_object_iter_next(struct json_object_iterator* iter);
|
||||
|
||||
|
||||
/** Returns a const pointer to the name of the pair referenced
|
||||
* by the given iterator.
|
||||
*
|
||||
* @param iter pointer to iterator that references a name/value
|
||||
* pair; MUST be a valid, non-end iterator.
|
||||
*
|
||||
* @warning bad things will happen if an invalid or
|
||||
* "end" iterator is passed.
|
||||
*
|
||||
* @return const char* Pointer to the name of the referenced
|
||||
* name/value pair. The name memory belongs to the
|
||||
* name/value pair, will be freed when the pair is
|
||||
* deleted or modified, and MUST NOT be modified or
|
||||
* freed by the user.
|
||||
*/
|
||||
const char*
|
||||
json_object_iter_peek_name(const struct json_object_iterator* iter);
|
||||
|
||||
|
||||
/** Returns a pointer to the json-c instance representing the
|
||||
* value of the referenced name/value pair, without altering
|
||||
* the instance's reference count.
|
||||
*
|
||||
* @param iter pointer to iterator that references a name/value
|
||||
* pair; MUST be a valid, non-end iterator.
|
||||
*
|
||||
* @warning bad things will happen if invalid or
|
||||
* "end" iterator is passed.
|
||||
*
|
||||
* @return struct json_object* Pointer to the json-c value
|
||||
* instance of the referenced name/value pair; the
|
||||
* value's reference count is not changed by this
|
||||
* function: if you plan to hold on to this json-c node,
|
||||
* take a look at json_object_get() and
|
||||
* json_object_put(). IMPORTANT: json-c API represents
|
||||
* the JSON Null value as a NULL json_object instance
|
||||
* pointer.
|
||||
*/
|
||||
struct json_object*
|
||||
json_object_iter_peek_value(const struct json_object_iterator* iter);
|
||||
|
||||
|
||||
/** Tests two iterators for equality. Typically used to test
|
||||
* for end of iteration by comparing an iterator to the
|
||||
* corresponding "end" iterator (that was derived from the same
|
||||
* JSON Object instance).
|
||||
*
|
||||
* @note The reason we do not (and MUST NOT) provide
|
||||
* "json_object_iter_is_end(json_object_iterator* iter)"
|
||||
* type of API is because it would limit the underlying
|
||||
* representation of name/value containment (or force us
|
||||
* to add additional, otherwise unnecessary, fields to
|
||||
* the iterator structure). The equality test method, on
|
||||
* the other hand, permits us to cleanly abstract pretty
|
||||
* much any reasonable underlying representation.
|
||||
*
|
||||
* @param iter1 Pointer to first valid, non-NULL iterator
|
||||
* @param iter2 POinter to second valid, non-NULL iterator
|
||||
*
|
||||
* @warning if a NULL iterator pointer or an uninitialized
|
||||
* or invalid iterator, or iterators derived from
|
||||
* different JSON Object instances are passed, bad things
|
||||
* will happen!
|
||||
*
|
||||
* @return json_bool non-zero if iterators are equal (i.e., both
|
||||
* reference the same name/value pair or are both at
|
||||
* "end"); zero if they are not equal.
|
||||
*/
|
||||
json_bool
|
||||
json_object_iter_equal(const struct json_object_iterator* iter1,
|
||||
const struct json_object_iterator* iter2);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* JSON_OBJECT_ITERATOR_H */
|
||||
120
proxy_c/third-lib/json-c/include/json-c/json_pointer.h
Normal file
120
proxy_c/third-lib/json-c/include/json-c/json_pointer.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Alexadru Ardelean.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief JSON Pointer (RFC 6901) implementation for retrieving
|
||||
* objects from a json-c object tree.
|
||||
*/
|
||||
#ifndef _json_pointer_h_
|
||||
#define _json_pointer_h_
|
||||
|
||||
#include "json_object.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Retrieves a JSON sub-object from inside another JSON object
|
||||
* using the JSON pointer notation as defined in RFC 6901
|
||||
* https://tools.ietf.org/html/rfc6901
|
||||
*
|
||||
* The returned JSON sub-object is equivalent to parsing manually the
|
||||
* 'obj' JSON tree ; i.e. it's not a new object that is created, but rather
|
||||
* a pointer inside the JSON tree.
|
||||
*
|
||||
* Internally, this is equivalent to doing a series of 'json_object_object_get()'
|
||||
* and 'json_object_array_get_idx()' along the given 'path'.
|
||||
*
|
||||
* Note that the 'path' string supports 'printf()' type arguments, so, whatever
|
||||
* is added after the 'res' param will be treated as an argument for 'path'
|
||||
* Example: json_pointer_get(obj, "/foo/%d/%s", &res, 0, bar)
|
||||
* This means, that you need to escape '%' with '%%' (just like in printf())
|
||||
*
|
||||
* @param obj the json_object instance/tree from where to retrieve sub-objects
|
||||
* @param path a (RFC6901) string notation for the sub-object to retrieve
|
||||
* @param res a pointer where to store a reference to the json_object
|
||||
* associated with the given path
|
||||
*
|
||||
* @return negative if an error (or not found), or 0 if succeeded
|
||||
*/
|
||||
int json_pointer_get(struct json_object *obj, const char *path, struct json_object **res);
|
||||
|
||||
/**
|
||||
* This is a variant of 'json_pointer_get()' that supports printf() style arguments.
|
||||
*
|
||||
* Example: json_pointer_getf(obj, res, "/foo/%d/%s", 0, bak)
|
||||
* This also means that you need to escape '%' with '%%' (just like in printf())
|
||||
*
|
||||
* Please take into consideration all recommended 'printf()' format security
|
||||
* aspects when using this function.
|
||||
*
|
||||
* @param obj the json_object instance/tree to which to add a sub-object
|
||||
* @param res a pointer where to store a reference to the json_object
|
||||
* associated with the given path
|
||||
* @param path_fmt a printf() style format for the path
|
||||
*
|
||||
* @return negative if an error (or not found), or 0 if succeeded
|
||||
*/
|
||||
int json_pointer_getf(struct json_object *obj, struct json_object **res, const char *path_fmt, ...);
|
||||
|
||||
/**
|
||||
* Sets JSON object 'value' in the 'obj' tree at the location specified
|
||||
* by the 'path'. 'path' is JSON pointer notation as defined in RFC 6901
|
||||
* https://tools.ietf.org/html/rfc6901
|
||||
*
|
||||
* Note that 'obj' is a double pointer, mostly for the "" (empty string)
|
||||
* case, where the entire JSON object would be replaced by 'value'.
|
||||
* In the case of the "" path, the object at '*obj' will have it's refcount
|
||||
* decremented with 'json_object_put()' and the 'value' object will be assigned to it.
|
||||
*
|
||||
* For other cases (JSON sub-objects) ownership of 'value' will be transferred into
|
||||
* '*obj' via 'json_object_object_add()' & 'json_object_array_put_idx()', so the
|
||||
* only time the refcount should be decremented for 'value' is when the return value of
|
||||
* 'json_pointer_set()' is negative (meaning the 'value' object did not get set into '*obj').
|
||||
*
|
||||
* That also implies that 'json_pointer_set()' does not do any refcount incrementing.
|
||||
* (Just that single decrement that was mentioned above).
|
||||
*
|
||||
* Note that the 'path' string supports 'printf()' type arguments, so, whatever
|
||||
* is added after the 'value' param will be treated as an argument for 'path'
|
||||
* Example: json_pointer_set(obj, "/foo/%d/%s", value, 0, bak)
|
||||
* This means, that you need to escape '%' with '%%' (just like in printf())
|
||||
*
|
||||
* @param obj the json_object instance/tree to which to add a sub-object
|
||||
* @param path a (RFC6901) string notation for the sub-object to set in the tree
|
||||
* @param value object to set at path
|
||||
*
|
||||
* @return negative if an error (or not found), or 0 if succeeded
|
||||
*/
|
||||
int json_pointer_set(struct json_object **obj, const char *path, struct json_object *value);
|
||||
|
||||
/**
|
||||
* This is a variant of 'json_pointer_set()' that supports printf() style arguments.
|
||||
*
|
||||
* Example: json_pointer_setf(obj, value, "/foo/%d/%s", 0, bak)
|
||||
* This also means that you need to escape '%' with '%%' (just like in printf())
|
||||
*
|
||||
* Please take into consideration all recommended 'printf()' format security
|
||||
* aspects when using this function.
|
||||
*
|
||||
* @param obj the json_object instance/tree to which to add a sub-object
|
||||
* @param value object to set at path
|
||||
* @param path_fmt a printf() style format for the path
|
||||
*
|
||||
* @return negative if an error (or not found), or 0 if succeeded
|
||||
*/
|
||||
int json_pointer_setf(struct json_object **obj, struct json_object *value, const char *path_fmt, ...);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
216
proxy_c/third-lib/json-c/include/json-c/json_tokener.h
Normal file
216
proxy_c/third-lib/json-c/include/json-c/json_tokener.h
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* $Id: json_tokener.h,v 1.10 2006/07/25 03:24:50 mclark Exp $
|
||||
*
|
||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||
* Michael Clark <michael@metaparadigm.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Methods to parse an input string into a tree of json_object objects.
|
||||
*/
|
||||
#ifndef _json_tokener_h_
|
||||
#define _json_tokener_h_
|
||||
|
||||
#include <stddef.h>
|
||||
#include "json_object.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum json_tokener_error {
|
||||
json_tokener_success,
|
||||
json_tokener_continue,
|
||||
json_tokener_error_depth,
|
||||
json_tokener_error_parse_eof,
|
||||
json_tokener_error_parse_unexpected,
|
||||
json_tokener_error_parse_null,
|
||||
json_tokener_error_parse_boolean,
|
||||
json_tokener_error_parse_number,
|
||||
json_tokener_error_parse_array,
|
||||
json_tokener_error_parse_object_key_name,
|
||||
json_tokener_error_parse_object_key_sep,
|
||||
json_tokener_error_parse_object_value_sep,
|
||||
json_tokener_error_parse_string,
|
||||
json_tokener_error_parse_comment,
|
||||
json_tokener_error_size
|
||||
};
|
||||
|
||||
enum json_tokener_state {
|
||||
json_tokener_state_eatws,
|
||||
json_tokener_state_start,
|
||||
json_tokener_state_finish,
|
||||
json_tokener_state_null,
|
||||
json_tokener_state_comment_start,
|
||||
json_tokener_state_comment,
|
||||
json_tokener_state_comment_eol,
|
||||
json_tokener_state_comment_end,
|
||||
json_tokener_state_string,
|
||||
json_tokener_state_string_escape,
|
||||
json_tokener_state_escape_unicode,
|
||||
json_tokener_state_boolean,
|
||||
json_tokener_state_number,
|
||||
json_tokener_state_array,
|
||||
json_tokener_state_array_add,
|
||||
json_tokener_state_array_sep,
|
||||
json_tokener_state_object_field_start,
|
||||
json_tokener_state_object_field,
|
||||
json_tokener_state_object_field_end,
|
||||
json_tokener_state_object_value,
|
||||
json_tokener_state_object_value_add,
|
||||
json_tokener_state_object_sep,
|
||||
json_tokener_state_array_after_sep,
|
||||
json_tokener_state_object_field_start_after_sep,
|
||||
json_tokener_state_inf
|
||||
};
|
||||
|
||||
struct json_tokener_srec
|
||||
{
|
||||
enum json_tokener_state state, saved_state;
|
||||
struct json_object *obj;
|
||||
struct json_object *current;
|
||||
char *obj_field_name;
|
||||
};
|
||||
|
||||
#define JSON_TOKENER_DEFAULT_DEPTH 32
|
||||
|
||||
struct json_tokener
|
||||
{
|
||||
char *str;
|
||||
struct printbuf *pb;
|
||||
int max_depth, depth, is_double, st_pos, char_offset;
|
||||
enum json_tokener_error err;
|
||||
unsigned int ucs_char;
|
||||
char quote_char;
|
||||
struct json_tokener_srec *stack;
|
||||
int flags;
|
||||
};
|
||||
/**
|
||||
* @deprecated Unused in json-c code
|
||||
*/
|
||||
typedef struct json_tokener json_tokener;
|
||||
|
||||
/**
|
||||
* Be strict when parsing JSON input. Use caution with
|
||||
* this flag as what is considered valid may become more
|
||||
* restrictive from one release to the next, causing your
|
||||
* code to fail on previously working input.
|
||||
*
|
||||
* This flag is not set by default.
|
||||
*
|
||||
* @see json_tokener_set_flags()
|
||||
*/
|
||||
#define JSON_TOKENER_STRICT 0x01
|
||||
|
||||
/**
|
||||
* Given an error previously returned by json_tokener_get_error(),
|
||||
* return a human readable description of the error.
|
||||
*
|
||||
* @return a generic error message is returned if an invalid error value is provided.
|
||||
*/
|
||||
const char *json_tokener_error_desc(enum json_tokener_error jerr);
|
||||
|
||||
/**
|
||||
* Retrieve the error caused by the last call to json_tokener_parse_ex(),
|
||||
* or json_tokener_success if there is no error.
|
||||
*
|
||||
* When parsing a JSON string in pieces, if the tokener is in the middle
|
||||
* of parsing this will return json_tokener_continue.
|
||||
*
|
||||
* See also json_tokener_error_desc().
|
||||
*/
|
||||
JSON_EXPORT enum json_tokener_error json_tokener_get_error(struct json_tokener *tok);
|
||||
|
||||
JSON_EXPORT struct json_tokener* json_tokener_new(void);
|
||||
JSON_EXPORT struct json_tokener* json_tokener_new_ex(int depth);
|
||||
JSON_EXPORT void json_tokener_free(struct json_tokener *tok);
|
||||
JSON_EXPORT void json_tokener_reset(struct json_tokener *tok);
|
||||
JSON_EXPORT struct json_object* json_tokener_parse(const char *str);
|
||||
JSON_EXPORT struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error);
|
||||
|
||||
/**
|
||||
* Set flags that control how parsing will be done.
|
||||
*/
|
||||
JSON_EXPORT void json_tokener_set_flags(struct json_tokener *tok, int flags);
|
||||
|
||||
/**
|
||||
* Parse a string and return a non-NULL json_object if a valid JSON value
|
||||
* is found. The string does not need to be a JSON object or array;
|
||||
* it can also be a string, number or boolean value.
|
||||
*
|
||||
* A partial JSON string can be parsed. If the parsing is incomplete,
|
||||
* NULL will be returned and json_tokener_get_error() will return
|
||||
* json_tokener_continue.
|
||||
* json_tokener_parse_ex() can then be called with additional bytes in str
|
||||
* to continue the parsing.
|
||||
*
|
||||
* If json_tokener_parse_ex() returns NULL and the error is anything other than
|
||||
* json_tokener_continue, a fatal error has occurred and parsing must be
|
||||
* halted. Then, the tok object must not be reused until json_tokener_reset() is
|
||||
* called.
|
||||
*
|
||||
* When a valid JSON value is parsed, a non-NULL json_object will be
|
||||
* returned. Also, json_tokener_get_error() will return json_tokener_success.
|
||||
* Be sure to check the type with json_object_is_type() or
|
||||
* json_object_get_type() before using the object.
|
||||
*
|
||||
* @b XXX this shouldn't use internal fields:
|
||||
* Trailing characters after the parsed value do not automatically cause an
|
||||
* error. It is up to the caller to decide whether to treat this as an
|
||||
* error or to handle the additional characters, perhaps by parsing another
|
||||
* json value starting from that point.
|
||||
*
|
||||
* Extra characters can be detected by comparing the tok->char_offset against
|
||||
* the length of the last len parameter passed in.
|
||||
*
|
||||
* The tokener does \b not maintain an internal buffer so the caller is
|
||||
* responsible for calling json_tokener_parse_ex with an appropriate str
|
||||
* parameter starting with the extra characters.
|
||||
*
|
||||
* This interface is presently not 64-bit clean due to the int len argument
|
||||
* so the function limits the maximum string size to INT32_MAX (2GB).
|
||||
* If the function is called with len == -1 then strlen is called to check
|
||||
* the string length is less than INT32_MAX (2GB)
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
json_object *jobj = NULL;
|
||||
const char *mystring = NULL;
|
||||
int stringlen = 0;
|
||||
enum json_tokener_error jerr;
|
||||
do {
|
||||
mystring = ... // get JSON string, e.g. read from file, etc...
|
||||
stringlen = strlen(mystring);
|
||||
jobj = json_tokener_parse_ex(tok, mystring, stringlen);
|
||||
} while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
|
||||
if (jerr != json_tokener_success)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
|
||||
// Handle errors, as appropriate for your application.
|
||||
}
|
||||
if (tok->char_offset < stringlen) // XXX shouldn't access internal fields
|
||||
{
|
||||
// Handle extra characters after parsed object as desired.
|
||||
// e.g. issue an error, parse another object from that point, etc...
|
||||
}
|
||||
// Success, use jobj here.
|
||||
|
||||
@endcode
|
||||
*
|
||||
* @param tok a json_tokener previously allocated with json_tokener_new()
|
||||
* @param str an string with any valid JSON expression, or portion of. This does not need to be null terminated.
|
||||
* @param len the length of str
|
||||
*/
|
||||
JSON_EXPORT struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
||||
const char *str, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
106
proxy_c/third-lib/json-c/include/json-c/json_util.h
Normal file
106
proxy_c/third-lib/json-c/include/json-c/json_util.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* $Id: json_util.h,v 1.4 2006/01/30 23:07:57 mclark Exp $
|
||||
*
|
||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||
* Michael Clark <michael@metaparadigm.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Miscllaneous utility functions and macros.
|
||||
*/
|
||||
#ifndef _json_util_h_
|
||||
#define _json_util_h_
|
||||
|
||||
#include "json_object.h"
|
||||
|
||||
#ifndef json_min
|
||||
#define json_min(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef json_max
|
||||
#define json_max(a,b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define JSON_FILE_BUF_SIZE 4096
|
||||
|
||||
/* utility functions */
|
||||
/**
|
||||
* Read the full contents of the given file, then convert it to a
|
||||
* json_object using json_tokener_parse().
|
||||
*
|
||||
* Returns -1 if something fails. See json_util_get_last_err() for details.
|
||||
*/
|
||||
extern struct json_object* json_object_from_file(const char *filename);
|
||||
|
||||
/**
|
||||
* Create a JSON object from already opened file descriptor.
|
||||
*
|
||||
* This function can be helpful, when you opened the file already,
|
||||
* e.g. when you have a temp file.
|
||||
* Note, that the fd must be readable at the actual position, i.e.
|
||||
* use lseek(fd, 0, SEEK_SET) before.
|
||||
*
|
||||
* Returns -1 if something fails. See json_util_get_last_err() for details.
|
||||
*/
|
||||
extern struct json_object* json_object_from_fd(int fd);
|
||||
|
||||
/**
|
||||
* Equivalent to:
|
||||
* json_object_to_file_ext(filename, obj, JSON_C_TO_STRING_PLAIN);
|
||||
*
|
||||
* Returns -1 if something fails. See json_util_get_last_err() for details.
|
||||
*/
|
||||
extern int json_object_to_file(const char *filename, struct json_object *obj);
|
||||
|
||||
/**
|
||||
* Open and truncate the given file, creating it if necessary, then
|
||||
* convert the json_object to a string and write it to the file.
|
||||
*
|
||||
* Returns -1 if something fails. See json_util_get_last_err() for details.
|
||||
*/
|
||||
extern int json_object_to_file_ext(const char *filename, struct json_object *obj, int flags);
|
||||
|
||||
/**
|
||||
* Convert the json_object to a string and write it to the file descriptor.
|
||||
* Handles partial writes and will keep writing until done, or an error
|
||||
* occurs.
|
||||
*
|
||||
* @param fd an open, writable file descriptor to write to
|
||||
* @param obj the object to serializer and write
|
||||
* @param flags flags to pass to json_object_to_json_string_ext()
|
||||
* @return -1 if something fails. See json_util_get_last_err() for details.
|
||||
*/
|
||||
extern int json_object_to_fd(int fd, struct json_object *obj, int flags);
|
||||
|
||||
/**
|
||||
* Return the last error from various json-c functions, including:
|
||||
* json_object_to_file{,_ext}, json_object_to_fd() or
|
||||
* json_object_from_{file,fd}, or NULL if there is none.
|
||||
*/
|
||||
const char *json_util_get_last_err(void);
|
||||
|
||||
|
||||
extern int json_parse_int64(const char *buf, int64_t *retval);
|
||||
extern int json_parse_double(const char *buf, double *retval);
|
||||
|
||||
/**
|
||||
* Return a string describing the type of the object.
|
||||
* e.g. "int", or "object", etc...
|
||||
*/
|
||||
extern const char *json_type_to_name(enum json_type o_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
381
proxy_c/third-lib/json-c/include/json-c/linkhash.h
Normal file
381
proxy_c/third-lib/json-c/include/json-c/linkhash.h
Normal file
@@ -0,0 +1,381 @@
|
||||
/*
|
||||
* $Id: linkhash.h,v 1.6 2006/01/30 23:07:57 mclark Exp $
|
||||
*
|
||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||
* Michael Clark <michael@metaparadigm.com>
|
||||
* Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Internal methods for working with json_type_object objects. Although
|
||||
* this is exposed by the json_object_get_object() function and within the
|
||||
* json_object_iter type, it is not recommended for direct use.
|
||||
*/
|
||||
#ifndef _linkhash_h_
|
||||
#define _linkhash_h_
|
||||
|
||||
#include "json_object.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* golden prime used in hash functions
|
||||
*/
|
||||
#define LH_PRIME 0x9e370001UL
|
||||
|
||||
/**
|
||||
* The fraction of filled hash buckets until an insert will cause the table
|
||||
* to be resized.
|
||||
* This can range from just above 0 up to 1.0.
|
||||
*/
|
||||
#define LH_LOAD_FACTOR 0.66
|
||||
|
||||
/**
|
||||
* sentinel pointer value for empty slots
|
||||
*/
|
||||
#define LH_EMPTY (void*)-1
|
||||
|
||||
/**
|
||||
* sentinel pointer value for freed slots
|
||||
*/
|
||||
#define LH_FREED (void*)-2
|
||||
|
||||
/**
|
||||
* default string hash function
|
||||
*/
|
||||
#define JSON_C_STR_HASH_DFLT 0
|
||||
|
||||
/**
|
||||
* perl-like string hash function
|
||||
*/
|
||||
#define JSON_C_STR_HASH_PERLLIKE 1
|
||||
|
||||
/**
|
||||
* This function sets the hash function to be used for strings.
|
||||
* Must be one of the JSON_C_STR_HASH_* values.
|
||||
* @returns 0 - ok, -1 if parameter was invalid
|
||||
*/
|
||||
int json_global_set_string_hash(const int h);
|
||||
|
||||
struct lh_entry;
|
||||
|
||||
/**
|
||||
* callback function prototypes
|
||||
*/
|
||||
typedef void (lh_entry_free_fn) (struct lh_entry *e);
|
||||
/**
|
||||
* callback function prototypes
|
||||
*/
|
||||
typedef unsigned long (lh_hash_fn) (const void *k);
|
||||
/**
|
||||
* callback function prototypes
|
||||
*/
|
||||
typedef int (lh_equal_fn) (const void *k1, const void *k2);
|
||||
|
||||
/**
|
||||
* An entry in the hash table
|
||||
*/
|
||||
struct lh_entry {
|
||||
/**
|
||||
* The key. Use lh_entry_k() instead of accessing this directly.
|
||||
*/
|
||||
const void *k;
|
||||
/**
|
||||
* A flag for users of linkhash to know whether or not they
|
||||
* need to free k.
|
||||
*/
|
||||
int k_is_constant;
|
||||
/**
|
||||
* The value. Use lh_entry_v() instead of accessing this directly.
|
||||
*/
|
||||
const void *v;
|
||||
/**
|
||||
* The next entry
|
||||
*/
|
||||
struct lh_entry *next;
|
||||
/**
|
||||
* The previous entry.
|
||||
*/
|
||||
struct lh_entry *prev;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The hash table structure.
|
||||
*/
|
||||
struct lh_table {
|
||||
/**
|
||||
* Size of our hash.
|
||||
*/
|
||||
int size;
|
||||
/**
|
||||
* Numbers of entries.
|
||||
*/
|
||||
int count;
|
||||
|
||||
/**
|
||||
* The first entry.
|
||||
*/
|
||||
struct lh_entry *head;
|
||||
|
||||
/**
|
||||
* The last entry.
|
||||
*/
|
||||
struct lh_entry *tail;
|
||||
|
||||
struct lh_entry *table;
|
||||
|
||||
/**
|
||||
* A pointer onto the function responsible for freeing an entry.
|
||||
*/
|
||||
lh_entry_free_fn *free_fn;
|
||||
lh_hash_fn *hash_fn;
|
||||
lh_equal_fn *equal_fn;
|
||||
};
|
||||
typedef struct lh_table lh_table;
|
||||
|
||||
|
||||
/**
|
||||
* Convenience list iterator.
|
||||
*/
|
||||
#define lh_foreach(table, entry) \
|
||||
for(entry = table->head; entry; entry = entry->next)
|
||||
|
||||
/**
|
||||
* lh_foreach_safe allows calling of deletion routine while iterating.
|
||||
*
|
||||
* @param table a struct lh_table * to iterate over
|
||||
* @param entry a struct lh_entry * variable to hold each element
|
||||
* @param tmp a struct lh_entry * variable to hold a temporary pointer to the next element
|
||||
*/
|
||||
#define lh_foreach_safe(table, entry, tmp) \
|
||||
for(entry = table->head; entry && ((tmp = entry->next) || 1); entry = tmp)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a new linkhash table.
|
||||
*
|
||||
* @param size initial table size. The table is automatically resized
|
||||
* although this incurs a performance penalty.
|
||||
* @param free_fn callback function used to free memory for entries
|
||||
* when lh_table_free or lh_table_delete is called.
|
||||
* If NULL is provided, then memory for keys and values
|
||||
* must be freed by the caller.
|
||||
* @param hash_fn function used to hash keys. 2 standard ones are defined:
|
||||
* lh_ptr_hash and lh_char_hash for hashing pointer values
|
||||
* and C strings respectively.
|
||||
* @param equal_fn comparison function to compare keys. 2 standard ones defined:
|
||||
* lh_ptr_hash and lh_char_hash for comparing pointer values
|
||||
* and C strings respectively.
|
||||
* @return On success, a pointer to the new linkhash table is returned.
|
||||
* On error, a null pointer is returned.
|
||||
*/
|
||||
extern struct lh_table* lh_table_new(int size,
|
||||
lh_entry_free_fn *free_fn,
|
||||
lh_hash_fn *hash_fn,
|
||||
lh_equal_fn *equal_fn);
|
||||
|
||||
/**
|
||||
* Convenience function to create a new linkhash table with char keys.
|
||||
*
|
||||
* @param size initial table size.
|
||||
* @param free_fn callback function used to free memory for entries.
|
||||
* @return On success, a pointer to the new linkhash table is returned.
|
||||
* On error, a null pointer is returned.
|
||||
*/
|
||||
extern struct lh_table* lh_kchar_table_new(int size,
|
||||
lh_entry_free_fn *free_fn);
|
||||
|
||||
|
||||
/**
|
||||
* Convenience function to create a new linkhash table with ptr keys.
|
||||
*
|
||||
* @param size initial table size.
|
||||
* @param free_fn callback function used to free memory for entries.
|
||||
* @return On success, a pointer to the new linkhash table is returned.
|
||||
* On error, a null pointer is returned.
|
||||
*/
|
||||
extern struct lh_table* lh_kptr_table_new(int size,
|
||||
lh_entry_free_fn *free_fn);
|
||||
|
||||
|
||||
/**
|
||||
* Free a linkhash table.
|
||||
*
|
||||
* If a lh_entry_free_fn callback free function was provided then it is
|
||||
* called for all entries in the table.
|
||||
*
|
||||
* @param t table to free.
|
||||
*/
|
||||
extern void lh_table_free(struct lh_table *t);
|
||||
|
||||
|
||||
/**
|
||||
* Insert a record into the table.
|
||||
*
|
||||
* @param t the table to insert into.
|
||||
* @param k a pointer to the key to insert.
|
||||
* @param v a pointer to the value to insert.
|
||||
*
|
||||
* @return On success, <code>0</code> is returned.
|
||||
* On error, a negative value is returned.
|
||||
*/
|
||||
extern int lh_table_insert(struct lh_table *t, const void *k, const void *v);
|
||||
|
||||
|
||||
/**
|
||||
* Insert a record into the table using a precalculated key hash.
|
||||
*
|
||||
* The hash h, which should be calculated with lh_get_hash() on k, is provided by
|
||||
* the caller, to allow for optimization when multiple operations with the same
|
||||
* key are known to be needed.
|
||||
*
|
||||
* @param t the table to insert into.
|
||||
* @param k a pointer to the key to insert.
|
||||
* @param v a pointer to the value to insert.
|
||||
* @param h hash value of the key to insert
|
||||
* @param opts if set to JSON_C_OBJECT_KEY_IS_CONSTANT, sets lh_entry.k_is_constant
|
||||
* so t's free function knows to avoid freeing the key.
|
||||
*/
|
||||
extern int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, const unsigned long h, const unsigned opts);
|
||||
|
||||
|
||||
/**
|
||||
* Lookup a record in the table.
|
||||
*
|
||||
* @param t the table to lookup
|
||||
* @param k a pointer to the key to lookup
|
||||
* @return a pointer to the record structure of the value or NULL if it does not exist.
|
||||
*/
|
||||
extern struct lh_entry* lh_table_lookup_entry(struct lh_table *t, const void *k);
|
||||
|
||||
/**
|
||||
* Lookup a record in the table using a precalculated key hash.
|
||||
*
|
||||
* The hash h, which should be calculated with lh_get_hash() on k, is provided by
|
||||
* the caller, to allow for optimization when multiple operations with the same
|
||||
* key are known to be needed.
|
||||
*
|
||||
* @param t the table to lookup
|
||||
* @param k a pointer to the key to lookup
|
||||
* @param h hash value of the key to lookup
|
||||
* @return a pointer to the record structure of the value or NULL if it does not exist.
|
||||
*/
|
||||
extern struct lh_entry* lh_table_lookup_entry_w_hash(struct lh_table *t, const void *k, const unsigned long h);
|
||||
|
||||
/**
|
||||
* Lookup a record in the table.
|
||||
*
|
||||
* @param t the table to lookup
|
||||
* @param k a pointer to the key to lookup
|
||||
* @param v a pointer to a where to store the found value (set to NULL if it doesn't exist).
|
||||
* @return whether or not the key was found
|
||||
*/
|
||||
extern json_bool lh_table_lookup_ex(struct lh_table *t, const void *k, void **v);
|
||||
|
||||
/**
|
||||
* Delete a record from the table.
|
||||
*
|
||||
* If a callback free function is provided then it is called for the
|
||||
* for the item being deleted.
|
||||
* @param t the table to delete from.
|
||||
* @param e a pointer to the entry to delete.
|
||||
* @return 0 if the item was deleted.
|
||||
* @return -1 if it was not found.
|
||||
*/
|
||||
extern int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e);
|
||||
|
||||
|
||||
/**
|
||||
* Delete a record from the table.
|
||||
*
|
||||
* If a callback free function is provided then it is called for the
|
||||
* for the item being deleted.
|
||||
* @param t the table to delete from.
|
||||
* @param k a pointer to the key to delete.
|
||||
* @return 0 if the item was deleted.
|
||||
* @return -1 if it was not found.
|
||||
*/
|
||||
extern int lh_table_delete(struct lh_table *t, const void *k);
|
||||
|
||||
extern int lh_table_length(struct lh_table *t);
|
||||
|
||||
/**
|
||||
* Resizes the specified table.
|
||||
*
|
||||
* @param t Pointer to table to resize.
|
||||
* @param new_size New table size. Must be positive.
|
||||
*
|
||||
* @return On success, <code>0</code> is returned.
|
||||
* On error, a negative value is returned.
|
||||
*/
|
||||
int lh_table_resize(struct lh_table *t, int new_size);
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Don't use this outside of linkhash.h:
|
||||
*/
|
||||
#if !defined(_MSC_VER) || (_MSC_VER > 1800)
|
||||
/* VS2010 can't handle inline funcs, so skip it there */
|
||||
#define _LH_INLINE inline
|
||||
#else
|
||||
#define _LH_INLINE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Calculate the hash of a key for a given table.
|
||||
*
|
||||
* This is an exension to support functions that need to calculate
|
||||
* the hash several times and allows them to do it just once and then pass
|
||||
* in the hash to all utility functions. Depending on use case, this can be a
|
||||
* considerable performance improvement.
|
||||
* @param t the table (used to obtain hash function)
|
||||
* @param k a pointer to the key to lookup
|
||||
* @return the key's hash
|
||||
*/
|
||||
static _LH_INLINE unsigned long lh_get_hash(const struct lh_table *t, const void *k)
|
||||
{
|
||||
return t->hash_fn(k);
|
||||
}
|
||||
|
||||
#undef _LH_INLINE
|
||||
|
||||
/**
|
||||
* @deprecated Don't use this outside of linkhash.h:
|
||||
*/
|
||||
#ifdef __UNCONST
|
||||
#define _LH_UNCONST(a) __UNCONST(a)
|
||||
#else
|
||||
#define _LH_UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Return a non-const version of lh_entry.k.
|
||||
*
|
||||
* lh_entry.k is const to indicate and help ensure that linkhash itself doesn't modify
|
||||
* it, but callers are allowed to do what they want with it.
|
||||
* See also lh_entry.k_is_constant
|
||||
*/
|
||||
#define lh_entry_k(entry) _LH_UNCONST((entry)->k)
|
||||
|
||||
/**
|
||||
* Return a non-const version of lh_entry.v.
|
||||
*
|
||||
* v is const to indicate and help ensure that linkhash itself doesn't modify
|
||||
* it, but callers are allowed to do what they want with it.
|
||||
*/
|
||||
#define lh_entry_v(entry) _LH_UNCONST((entry)->v)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
122
proxy_c/third-lib/json-c/include/json-c/printbuf.h
Normal file
122
proxy_c/third-lib/json-c/include/json-c/printbuf.h
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* $Id: printbuf.h,v 1.4 2006/01/26 02:16:28 mclark Exp $
|
||||
*
|
||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||
* Michael Clark <michael@metaparadigm.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2008-2009 Yahoo! Inc. All rights reserved.
|
||||
* The copyrights to the contents of this file are licensed under the MIT License
|
||||
* (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Internal string buffer handing. Unless you're writing a
|
||||
* json_object_to_json_string_fn implementation for use with
|
||||
* json_object_set_serializer() direct use of this is not
|
||||
* recommended.
|
||||
*/
|
||||
#ifndef _printbuf_h_
|
||||
#define _printbuf_h_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct printbuf {
|
||||
char *buf;
|
||||
int bpos;
|
||||
int size;
|
||||
};
|
||||
typedef struct printbuf printbuf;
|
||||
|
||||
extern struct printbuf*
|
||||
printbuf_new(void);
|
||||
|
||||
/* As an optimization, printbuf_memappend_fast() is defined as a macro
|
||||
* that handles copying data if the buffer is large enough; otherwise
|
||||
* it invokes printbuf_memappend() which performs the heavy
|
||||
* lifting of realloc()ing the buffer and copying data.
|
||||
*
|
||||
* Your code should not use printbuf_memappend() directly unless it
|
||||
* checks the return code. Use printbuf_memappend_fast() instead.
|
||||
*/
|
||||
extern int
|
||||
printbuf_memappend(struct printbuf *p, const char *buf, int size);
|
||||
|
||||
#define printbuf_memappend_fast(p, bufptr, bufsize) \
|
||||
do { \
|
||||
if ((p->size - p->bpos) > bufsize) { \
|
||||
memcpy(p->buf + p->bpos, (bufptr), bufsize); \
|
||||
p->bpos += bufsize; \
|
||||
p->buf[p->bpos]= '\0'; \
|
||||
} else { printbuf_memappend(p, (bufptr), bufsize); } \
|
||||
} while (0)
|
||||
|
||||
#define printbuf_length(p) ((p)->bpos)
|
||||
|
||||
/**
|
||||
* Results in a compile error if the argument is not a string literal.
|
||||
*/
|
||||
#define _printbuf_check_literal(mystr) ("" mystr)
|
||||
|
||||
/**
|
||||
* This is an optimization wrapper around printbuf_memappend() that is useful
|
||||
* for appending string literals. Since the size of string constants is known
|
||||
* at compile time, using this macro can avoid a costly strlen() call. This is
|
||||
* especially helpful when a constant string must be appended many times. If
|
||||
* you got here because of a compilation error caused by passing something
|
||||
* other than a string literal, use printbuf_memappend_fast() in conjunction
|
||||
* with strlen().
|
||||
*
|
||||
* See also:
|
||||
* printbuf_memappend_fast()
|
||||
* printbuf_memappend()
|
||||
* sprintbuf()
|
||||
*/
|
||||
#define printbuf_strappend(pb, str) \
|
||||
printbuf_memappend ((pb), _printbuf_check_literal(str), sizeof(str) - 1)
|
||||
|
||||
/**
|
||||
* Set len bytes of the buffer to charvalue, starting at offset offset.
|
||||
* Similar to calling memset(x, charvalue, len);
|
||||
*
|
||||
* The memory allocated for the buffer is extended as necessary.
|
||||
*
|
||||
* If offset is -1, this starts at the end of the current data in the buffer.
|
||||
*/
|
||||
extern int
|
||||
printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len);
|
||||
|
||||
/**
|
||||
* Formatted print to printbuf.
|
||||
*
|
||||
* This function is the most expensive of the available functions for appending
|
||||
* string data to a printbuf and should be used only where convenience is more
|
||||
* important than speed. Avoid using this function in high performance code or
|
||||
* tight loops; in these scenarios, consider using snprintf() with a static
|
||||
* buffer in conjunction with one of the printbuf_*append() functions.
|
||||
*
|
||||
* See also:
|
||||
* printbuf_memappend_fast()
|
||||
* printbuf_memappend()
|
||||
* printbuf_strappend()
|
||||
*/
|
||||
extern int
|
||||
sprintbuf(struct printbuf *p, const char *msg, ...);
|
||||
|
||||
extern void
|
||||
printbuf_reset(struct printbuf *p);
|
||||
|
||||
extern void
|
||||
printbuf_free(struct printbuf *p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
146
proxy_c/third-lib/json-c/src/arraylist.c
Normal file
146
proxy_c/third-lib/json-c/src/arraylist.c
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* $Id: arraylist.c,v 1.4 2006/01/26 02:16:28 mclark Exp $
|
||||
*
|
||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||
* Michael Clark <michael@metaparadigm.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config_json_c.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
#endif /* STDC_HEADERS */
|
||||
|
||||
#if defined(HAVE_STRINGS_H) && !defined(_STRING_H) && !defined(__USE_BSD)
|
||||
# include <strings.h>
|
||||
#endif /* HAVE_STRINGS_H */
|
||||
|
||||
#ifndef SIZE_T_MAX
|
||||
#if SIZEOF_SIZE_T == SIZEOF_INT
|
||||
#define SIZE_T_MAX UINT_MAX
|
||||
#elif SIZEOF_SIZE_T == SIZEOF_LONG
|
||||
#define SIZE_T_MAX ULONG_MAX
|
||||
#elif SIZEOF_SIZE_T == SIZEOF_LONG_LONG
|
||||
#define SIZE_T_MAX ULLONG_MAX
|
||||
#else
|
||||
#error Unable to determine size of size_t
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "arraylist.h"
|
||||
|
||||
struct array_list*
|
||||
array_list_new(array_list_free_fn *free_fn)
|
||||
{
|
||||
struct array_list *arr;
|
||||
|
||||
arr = (struct array_list*)calloc(1, sizeof(struct array_list));
|
||||
if(!arr) return NULL;
|
||||
arr->size = ARRAY_LIST_DEFAULT_SIZE;
|
||||
arr->length = 0;
|
||||
arr->free_fn = free_fn;
|
||||
if(!(arr->array = (void**)calloc(sizeof(void*), arr->size))) {
|
||||
free(arr);
|
||||
return NULL;
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
extern void
|
||||
array_list_free(struct array_list *arr)
|
||||
{
|
||||
size_t i;
|
||||
for(i = 0; i < arr->length; i++)
|
||||
if(arr->array[i]) arr->free_fn(arr->array[i]);
|
||||
free(arr->array);
|
||||
free(arr);
|
||||
}
|
||||
|
||||
void*
|
||||
array_list_get_idx(struct array_list *arr, size_t i)
|
||||
{
|
||||
if(i >= arr->length) return NULL;
|
||||
return arr->array[i];
|
||||
}
|
||||
|
||||
static int array_list_expand_internal(struct array_list *arr, size_t max)
|
||||
{
|
||||
void *t;
|
||||
size_t new_size;
|
||||
|
||||
if(max < arr->size) return 0;
|
||||
/* Avoid undefined behaviour on size_t overflow */
|
||||
if( arr->size >= SIZE_T_MAX / 2 )
|
||||
new_size = max;
|
||||
else
|
||||
{
|
||||
new_size = arr->size << 1;
|
||||
if (new_size < max)
|
||||
new_size = max;
|
||||
}
|
||||
if (new_size > (~((size_t)0)) / sizeof(void*)) return -1;
|
||||
if (!(t = realloc(arr->array, new_size*sizeof(void*)))) return -1;
|
||||
arr->array = (void**)t;
|
||||
(void)memset(arr->array + arr->size, 0, (new_size-arr->size)*sizeof(void*));
|
||||
arr->size = new_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
array_list_put_idx(struct array_list *arr, size_t idx, void *data)
|
||||
{
|
||||
if (idx > SIZE_T_MAX - 1 ) return -1;
|
||||
if(array_list_expand_internal(arr, idx+1)) return -1;
|
||||
if(idx < arr->length && arr->array[idx])
|
||||
arr->free_fn(arr->array[idx]);
|
||||
arr->array[idx] = data;
|
||||
if(arr->length <= idx) arr->length = idx + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
array_list_add(struct array_list *arr, void *data)
|
||||
{
|
||||
return array_list_put_idx(arr, arr->length, data);
|
||||
}
|
||||
|
||||
void
|
||||
array_list_sort(struct array_list *arr, int(*sort_fn)(const void *, const void *))
|
||||
{
|
||||
qsort(arr->array, arr->length, sizeof(arr->array[0]), sort_fn);
|
||||
}
|
||||
|
||||
void* array_list_bsearch(const void **key, struct array_list *arr,
|
||||
int (*sort_fn)(const void *, const void *))
|
||||
{
|
||||
return bsearch(key, arr->array, arr->length, sizeof(arr->array[0]),
|
||||
sort_fn);
|
||||
}
|
||||
|
||||
size_t
|
||||
array_list_length(struct array_list *arr)
|
||||
{
|
||||
return arr->length;
|
||||
}
|
||||
|
||||
int
|
||||
array_list_del_idx( struct array_list *arr, size_t idx, size_t count )
|
||||
{
|
||||
size_t i, stop;
|
||||
|
||||
stop = idx + count;
|
||||
if ( idx >= arr->length || stop > arr->length ) return -1;
|
||||
for ( i = idx; i < stop; ++i ) {
|
||||
if ( arr->array[i] ) arr->free_fn( arr->array[i] );
|
||||
}
|
||||
memmove( arr->array + idx, arr->array + stop, (arr->length - stop) * sizeof(void*) );
|
||||
arr->length -= count;
|
||||
return 0;
|
||||
}
|
||||
70
proxy_c/third-lib/json-c/src/arraylist.h
Normal file
70
proxy_c/third-lib/json-c/src/arraylist.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* $Id: arraylist.h,v 1.4 2006/01/26 02:16:28 mclark Exp $
|
||||
*
|
||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||
* Michael Clark <michael@metaparadigm.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Internal methods for working with json_type_array objects.
|
||||
* Although this is exposed by the json_object_get_array() method,
|
||||
* it is not recommended for direct use.
|
||||
*/
|
||||
#ifndef _arraylist_h_
|
||||
#define _arraylist_h_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ARRAY_LIST_DEFAULT_SIZE 32
|
||||
|
||||
typedef void (array_list_free_fn) (void *data);
|
||||
|
||||
struct array_list
|
||||
{
|
||||
void **array;
|
||||
size_t length;
|
||||
size_t size;
|
||||
array_list_free_fn *free_fn;
|
||||
};
|
||||
typedef struct array_list array_list;
|
||||
|
||||
extern struct array_list*
|
||||
array_list_new(array_list_free_fn *free_fn);
|
||||
|
||||
extern void
|
||||
array_list_free(struct array_list *al);
|
||||
|
||||
extern void*
|
||||
array_list_get_idx(struct array_list *al, size_t i);
|
||||
|
||||
extern int
|
||||
array_list_put_idx(struct array_list *al, size_t i, void *data);
|
||||
|
||||
extern int
|
||||
array_list_add(struct array_list *al, void *data);
|
||||
|
||||
extern size_t
|
||||
array_list_length(struct array_list *al);
|
||||
|
||||
extern void
|
||||
array_list_sort(struct array_list *arr, int(*compar)(const void *, const void *));
|
||||
|
||||
extern void* array_list_bsearch(const void **key,
|
||||
struct array_list *arr,
|
||||
int (*sort_fn)(const void *, const void *));
|
||||
|
||||
extern int
|
||||
array_list_del_idx(struct array_list *arr, size_t idx, size_t count);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
200
proxy_c/third-lib/json-c/src/config_json_c.h
Normal file
200
proxy_c/third-lib/json-c/src/config_json_c.h
Normal file
@@ -0,0 +1,200 @@
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Enable RDRAND Hardware RNG Hash Seed */
|
||||
/* #undef ENABLE_RDRAND */
|
||||
|
||||
/* Enable partial threading support */
|
||||
/* #undef ENABLE_THREADING */
|
||||
|
||||
/* Define if .gnu.warning accepts long strings. */
|
||||
/* #undef HAS_GNU_WARNING_LONG */
|
||||
|
||||
/* Has atomic builtins */
|
||||
#define HAVE_ATOMIC_BUILTINS 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `INFINITY', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_INFINITY 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `isinf', and to 0 if you don't.
|
||||
*/
|
||||
#define HAVE_DECL_ISINF 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `isnan', and to 0 if you don't.
|
||||
*/
|
||||
#define HAVE_DECL_ISNAN 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `nan', and to 0 if you don't. */
|
||||
#define HAVE_DECL_NAN 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `_finite', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL__FINITE 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `_isnan', and to 0 if you don't.
|
||||
*/
|
||||
#define HAVE_DECL__ISNAN 0
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
|
||||
/* #undef HAVE_DOPRNT */
|
||||
|
||||
/* Define to 1 if you have the <endian.h> header file. */
|
||||
#define HAVE_ENDIAN_H 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#define HAVE_LOCALE_H 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `open' function. */
|
||||
#define HAVE_OPEN 1
|
||||
|
||||
/* Define to 1 if you have the `realloc' function. */
|
||||
#define HAVE_REALLOC 1
|
||||
|
||||
/* Define to 1 if you have the `setlocale' function. */
|
||||
#define HAVE_SETLOCALE 1
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
#define HAVE_SNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||
#define HAVE_STDARG_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strcasecmp' function. */
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#define HAVE_STRERROR 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strncasecmp' function. */
|
||||
#define HAVE_STRNCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#define HAVE_SYSLOG_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/cdefs.h> header file. */
|
||||
#define HAVE_SYS_CDEFS_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `uselocale' function. */
|
||||
#define HAVE_USELOCALE 1
|
||||
|
||||
/* Define to 1 if you have the `vasprintf' function. */
|
||||
//#define HAVE_VASPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `vprintf' function. */
|
||||
#define HAVE_VPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#define HAVE_VSNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `vsyslog' function. */
|
||||
#define HAVE_VSYSLOG 1
|
||||
|
||||
/* Define to 1 if you have the <xlocale.h> header file. */
|
||||
#define HAVE_XLOCALE_H 1
|
||||
|
||||
/* Have __thread */
|
||||
#define HAVE___THREAD 1
|
||||
|
||||
/* Public define for json_inttypes.h */
|
||||
#define JSON_C_HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
/* #undef NO_MINUS_C_MINUS_O */
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "json-c"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "json-c@googlegroups.com"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "json-c"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "json-c 0.13.99"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "json-c"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "0.13.99"
|
||||
|
||||
/* The number of bytes in type int */
|
||||
#define SIZEOF_INT 4
|
||||
|
||||
/* The number of bytes in type int64_t */
|
||||
#define SIZEOF_INT64_T 8
|
||||
|
||||
/* The number of bytes in type long */
|
||||
#define SIZEOF_LONG 8
|
||||
|
||||
/* The number of bytes in type long long */
|
||||
#define SIZEOF_LONG_LONG 8
|
||||
|
||||
/* The number of bytes in type size_t */
|
||||
#define SIZEOF_SIZE_T 8
|
||||
|
||||
/* Specifier for __thread */
|
||||
#define SPEC___THREAD __thread
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "0.13.99"
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
/* #undef size_t */
|
||||
83
proxy_c/third-lib/json-c/src/debug.c
Normal file
83
proxy_c/third-lib/json-c/src/debug.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* $Id: debug.c,v 1.5 2006/01/26 02:16:28 mclark Exp $
|
||||
*
|
||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||
* Michael Clark <michael@metaparadigm.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config_json_c.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#if HAVE_SYSLOG_H
|
||||
# include <syslog.h>
|
||||
#endif /* HAVE_SYSLOG_H */
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#if HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif /* HAVE_SYS_PARAM_H */
|
||||
|
||||
#include "debug.h"
|
||||
|
||||
static int _syslog = 0;
|
||||
static int _debug = 0;
|
||||
|
||||
void mc_set_debug(int debug) { _debug = debug; }
|
||||
int mc_get_debug(void) { return _debug; }
|
||||
|
||||
extern void mc_set_syslog(int syslog)
|
||||
{
|
||||
_syslog = syslog;
|
||||
}
|
||||
|
||||
void mc_debug(const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
if(_debug) {
|
||||
va_start(ap, msg);
|
||||
#if HAVE_VSYSLOG
|
||||
if(_syslog) {
|
||||
vsyslog(LOG_DEBUG, msg, ap);
|
||||
} else
|
||||
#endif
|
||||
vprintf(msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
|
||||
void mc_error(const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
#if HAVE_VSYSLOG
|
||||
if(_syslog) {
|
||||
vsyslog(LOG_ERR, msg, ap);
|
||||
} else
|
||||
#endif
|
||||
vfprintf(stderr, msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void mc_info(const char *msg, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, msg);
|
||||
#if HAVE_VSYSLOG
|
||||
if(_syslog) {
|
||||
vsyslog(LOG_INFO, msg, ap);
|
||||
} else
|
||||
#endif
|
||||
vfprintf(stderr, msg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
75
proxy_c/third-lib/json-c/src/debug.h
Normal file
75
proxy_c/third-lib/json-c/src/debug.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* $Id: debug.h,v 1.5 2006/01/30 23:07:57 mclark Exp $
|
||||
*
|
||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||
* Michael Clark <michael@metaparadigm.com>
|
||||
* Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Do not use, json-c internal, may be changed or removed at any time.
|
||||
*/
|
||||
#ifndef _DEBUG_H_
|
||||
#define _DEBUG_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void mc_set_debug(int debug);
|
||||
extern int mc_get_debug(void);
|
||||
|
||||
extern void mc_set_syslog(int syslog);
|
||||
|
||||
extern void mc_debug(const char *msg, ...);
|
||||
extern void mc_error(const char *msg, ...);
|
||||
extern void mc_info(const char *msg, ...);
|
||||
|
||||
#ifndef __STRING
|
||||
#define __STRING(x) #x
|
||||
#endif
|
||||
|
||||
#ifndef PARSER_BROKEN_FIXED
|
||||
|
||||
#define JASSERT(cond) do {} while(0)
|
||||
|
||||
#else
|
||||
|
||||
#define JASSERT(cond) do { \
|
||||
if (!(cond)) { \
|
||||
mc_error("cjson assert failure %s:%d : cond \"" __STRING(cond) "failed\n", __FILE__, __LINE__); \
|
||||
*(int *)0 = 1;\
|
||||
abort(); \
|
||||
}\
|
||||
} while(0)
|
||||
|
||||
#endif
|
||||
|
||||
#define MC_ERROR(x, ...) mc_error(x, ##__VA_ARGS__)
|
||||
|
||||
#ifdef MC_MAINTAINER_MODE
|
||||
#define MC_SET_DEBUG(x) mc_set_debug(x)
|
||||
#define MC_GET_DEBUG() mc_get_debug()
|
||||
#define MC_SET_SYSLOG(x) mc_set_syslog(x)
|
||||
#define MC_DEBUG(x, ...) mc_debug(x, ##__VA_ARGS__)
|
||||
#define MC_INFO(x, ...) mc_info(x, ##__VA_ARGS__)
|
||||
#else
|
||||
#define MC_SET_DEBUG(x) if (0) mc_set_debug(x)
|
||||
#define MC_GET_DEBUG() (0)
|
||||
#define MC_SET_SYSLOG(x) if (0) mc_set_syslog(x)
|
||||
#define MC_DEBUG(x, ...) if (0) mc_debug(x, ##__VA_ARGS__)
|
||||
#define MC_INFO(x, ...) if (0) mc_info(x, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
38
proxy_c/third-lib/json-c/src/json.h
Normal file
38
proxy_c/third-lib/json-c/src/json.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* $Id: json.h,v 1.6 2006/01/26 02:16:28 mclark Exp $
|
||||
*
|
||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||
* Michael Clark <michael@metaparadigm.com>
|
||||
* Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief A convenience header that may be included instead of other individual ones.
|
||||
*/
|
||||
#ifndef _json_h_
|
||||
#define _json_h_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "debug.h"
|
||||
#include "linkhash.h"
|
||||
#include "arraylist.h"
|
||||
#include "json_util.h"
|
||||
#include "json_object.h"
|
||||
#include "json_pointer.h"
|
||||
#include "json_tokener.h"
|
||||
#include "json_object_iterator.h"
|
||||
#include "json_c_version.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
20
proxy_c/third-lib/json-c/src/json_c_version.c
Normal file
20
proxy_c/third-lib/json-c/src/json_c_version.c
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Eric Haszlakiewicz
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*/
|
||||
#include "config_json_c.h"
|
||||
|
||||
#include "json_c_version.h"
|
||||
|
||||
const char *json_c_version(void)
|
||||
{
|
||||
return JSON_C_VERSION;
|
||||
}
|
||||
|
||||
int json_c_version_num(void)
|
||||
{
|
||||
return JSON_C_VERSION_NUM;
|
||||
}
|
||||
|
||||
40
proxy_c/third-lib/json-c/src/json_c_version.h
Normal file
40
proxy_c/third-lib/json-c/src/json_c_version.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2012,2017 Eric Haszlakiewicz
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Methods for retrieving the json-c version.
|
||||
*/
|
||||
#ifndef _json_c_version_h_
|
||||
#define _json_c_version_h_
|
||||
|
||||
#define JSON_C_MAJOR_VERSION 0
|
||||
#define JSON_C_MINOR_VERSION 13
|
||||
#define JSON_C_MICRO_VERSION 99
|
||||
#define JSON_C_VERSION_NUM ((JSON_C_MAJOR_VERSION << 16) | \
|
||||
(JSON_C_MINOR_VERSION << 8) | \
|
||||
JSON_C_MICRO_VERSION)
|
||||
#define JSON_C_VERSION "0.13.99"
|
||||
|
||||
/**
|
||||
* @see JSON_C_VERSION
|
||||
* @return the version of the json-c library as a string
|
||||
*/
|
||||
const char *json_c_version(void); /* Returns JSON_C_VERSION */
|
||||
|
||||
/**
|
||||
* The json-c version encoded into an int, with the low order 8 bits
|
||||
* being the micro version, the next higher 8 bits being the minor version
|
||||
* and the next higher 8 bits being the major version.
|
||||
* For example, 7.12.99 would be 0x00070B63.
|
||||
*
|
||||
* @see JSON_C_VERSION_NUM
|
||||
* @return the version of the json-c library as an int
|
||||
*/
|
||||
int json_c_version_num(void); /* Returns JSON_C_VERSION_NUM */
|
||||
|
||||
#endif
|
||||
4
proxy_c/third-lib/json-c/src/json_config.h
Normal file
4
proxy_c/third-lib/json-c/src/json_config.h
Normal file
@@ -0,0 +1,4 @@
|
||||
/* json_config.h. Generated from json_config.h.in by configure. */
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define JSON_C_HAVE_INTTYPES_H 1
|
||||
23
proxy_c/third-lib/json-c/src/json_inttypes.h
Normal file
23
proxy_c/third-lib/json-c/src/json_inttypes.h
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Do not use, json-c internal, may be changed or removed at any time.
|
||||
*/
|
||||
#ifndef _json_inttypes_h_
|
||||
#define _json_inttypes_h_
|
||||
|
||||
#include "json_config.h"
|
||||
|
||||
#ifdef JSON_C_HAVE_INTTYPES_H
|
||||
/* inttypes.h includes stdint.h */
|
||||
#include <inttypes.h>
|
||||
|
||||
#else
|
||||
#include <stdint.h>
|
||||
|
||||
#define PRId64 "I64d"
|
||||
#define SCNd64 "I64d"
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1496
proxy_c/third-lib/json-c/src/json_object.c
Normal file
1496
proxy_c/third-lib/json-c/src/json_object.c
Normal file
File diff suppressed because it is too large
Load Diff
1028
proxy_c/third-lib/json-c/src/json_object.h
Normal file
1028
proxy_c/third-lib/json-c/src/json_object.h
Normal file
File diff suppressed because it is too large
Load Diff
163
proxy_c/third-lib/json-c/src/json_object_iterator.c
Normal file
163
proxy_c/third-lib/json-c/src/json_object_iterator.c
Normal file
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file json_object_iterator.c
|
||||
*
|
||||
* Copyright (c) 2009-2012 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "json.h"
|
||||
#include "json_object_private.h"
|
||||
|
||||
#include "json_object_iterator.h"
|
||||
|
||||
/**
|
||||
* How It Works
|
||||
*
|
||||
* For each JSON Object, json-c maintains a linked list of zero
|
||||
* or more lh_entry (link-hash entry) structures inside the
|
||||
* Object's link-hash table (lh_table).
|
||||
*
|
||||
* Each lh_entry structure on the JSON Object's linked list
|
||||
* represents a single name/value pair. The "next" field of the
|
||||
* last lh_entry in the list is set to NULL, which terminates
|
||||
* the list.
|
||||
*
|
||||
* We represent a valid iterator that refers to an actual
|
||||
* name/value pair via a pointer to the pair's lh_entry
|
||||
* structure set as the iterator's opaque_ field.
|
||||
*
|
||||
* We follow json-c's current pair list representation by
|
||||
* representing a valid "end" iterator (one that refers past the
|
||||
* last pair) with a NULL value in the iterator's opaque_ field.
|
||||
*
|
||||
* A JSON Object without any pairs in it will have the "head"
|
||||
* field of its lh_table structure set to NULL. For such an
|
||||
* object, json_object_iter_begin will return an iterator with
|
||||
* the opaque_ field set to NULL, which is equivalent to the
|
||||
* "end" iterator.
|
||||
*
|
||||
* When iterating, we simply update the iterator's opaque_ field
|
||||
* to point to the next lh_entry structure in the linked list.
|
||||
* opaque_ will become NULL once we iterate past the last pair
|
||||
* in the list, which makes the iterator equivalent to the "end"
|
||||
* iterator.
|
||||
*/
|
||||
|
||||
/// Our current representation of the "end" iterator;
|
||||
///
|
||||
/// @note May not always be NULL
|
||||
static const void* kObjectEndIterValue = NULL;
|
||||
|
||||
/**
|
||||
* ****************************************************************************
|
||||
*/
|
||||
struct json_object_iterator
|
||||
json_object_iter_begin(struct json_object* obj)
|
||||
{
|
||||
struct json_object_iterator iter;
|
||||
struct lh_table* pTable;
|
||||
|
||||
/// @note json_object_get_object will return NULL if passed NULL
|
||||
/// or a non-json_type_object instance
|
||||
pTable = json_object_get_object(obj);
|
||||
JASSERT(NULL != pTable);
|
||||
|
||||
/// @note For a pair-less Object, head is NULL, which matches our
|
||||
/// definition of the "end" iterator
|
||||
iter.opaque_ = pTable->head;
|
||||
return iter;
|
||||
}
|
||||
|
||||
/**
|
||||
* ****************************************************************************
|
||||
*/
|
||||
struct json_object_iterator
|
||||
json_object_iter_end(const struct json_object* obj)
|
||||
{
|
||||
struct json_object_iterator iter;
|
||||
|
||||
JASSERT(NULL != obj);
|
||||
JASSERT(json_object_is_type(obj, json_type_object));
|
||||
|
||||
iter.opaque_ = kObjectEndIterValue;
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
/**
|
||||
* ****************************************************************************
|
||||
*/
|
||||
void
|
||||
json_object_iter_next(struct json_object_iterator* iter)
|
||||
{
|
||||
JASSERT(NULL != iter);
|
||||
JASSERT(kObjectEndIterValue != iter->opaque_);
|
||||
|
||||
iter->opaque_ = ((const struct lh_entry *)iter->opaque_)->next;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ****************************************************************************
|
||||
*/
|
||||
const char*
|
||||
json_object_iter_peek_name(const struct json_object_iterator* iter)
|
||||
{
|
||||
JASSERT(NULL != iter);
|
||||
JASSERT(kObjectEndIterValue != iter->opaque_);
|
||||
|
||||
return (const char*)(((const struct lh_entry *)iter->opaque_)->k);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ****************************************************************************
|
||||
*/
|
||||
struct json_object*
|
||||
json_object_iter_peek_value(const struct json_object_iterator* iter)
|
||||
{
|
||||
JASSERT(NULL != iter);
|
||||
JASSERT(kObjectEndIterValue != iter->opaque_);
|
||||
|
||||
return (struct json_object*)lh_entry_v((const struct lh_entry *)iter->opaque_);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ****************************************************************************
|
||||
*/
|
||||
json_bool
|
||||
json_object_iter_equal(const struct json_object_iterator* iter1,
|
||||
const struct json_object_iterator* iter2)
|
||||
{
|
||||
JASSERT(NULL != iter1);
|
||||
JASSERT(NULL != iter2);
|
||||
|
||||
return (iter1->opaque_ == iter2->opaque_);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ****************************************************************************
|
||||
*/
|
||||
struct json_object_iterator
|
||||
json_object_iter_init_default(void)
|
||||
{
|
||||
struct json_object_iterator iter;
|
||||
|
||||
/**
|
||||
* @note Make this a negative, invalid value, such that
|
||||
* accidental access to it would likely be trapped by the
|
||||
* hardware as an invalid address.
|
||||
*/
|
||||
iter.opaque_ = NULL;
|
||||
|
||||
return iter;
|
||||
}
|
||||
240
proxy_c/third-lib/json-c/src/json_object_iterator.h
Normal file
240
proxy_c/third-lib/json-c/src/json_object_iterator.h
Normal file
@@ -0,0 +1,240 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* @file json_object_iterator.h
|
||||
*
|
||||
* Copyright (c) 2009-2012 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
* @brief An API for iterating over json_type_object objects,
|
||||
* styled to be familiar to C++ programmers.
|
||||
* Unlike json_object_object_foreach() and
|
||||
* json_object_object_foreachC(), this avoids the need to expose
|
||||
* json-c internals like lh_entry.
|
||||
*
|
||||
* API attributes: <br>
|
||||
* * Thread-safe: NO<br>
|
||||
* * Reentrant: NO
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#ifndef JSON_OBJECT_ITERATOR_H
|
||||
#define JSON_OBJECT_ITERATOR_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Forward declaration for the opaque iterator information.
|
||||
*/
|
||||
struct json_object_iter_info_;
|
||||
|
||||
/**
|
||||
* The opaque iterator that references a name/value pair within
|
||||
* a JSON Object instance or the "end" iterator value.
|
||||
*/
|
||||
struct json_object_iterator {
|
||||
const void* opaque_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* forward declaration of json-c's JSON value instance structure
|
||||
*/
|
||||
struct json_object;
|
||||
|
||||
|
||||
/**
|
||||
* Initializes an iterator structure to a "default" value that
|
||||
* is convenient for initializing an iterator variable to a
|
||||
* default state (e.g., initialization list in a class'
|
||||
* constructor).
|
||||
*
|
||||
* @code
|
||||
* struct json_object_iterator iter = json_object_iter_init_default();
|
||||
* MyClass() : iter_(json_object_iter_init_default())
|
||||
* @endcode
|
||||
*
|
||||
* @note The initialized value doesn't reference any specific
|
||||
* pair, is considered an invalid iterator, and MUST NOT
|
||||
* be passed to any json-c API that expects a valid
|
||||
* iterator.
|
||||
*
|
||||
* @note User and internal code MUST NOT make any assumptions
|
||||
* about and dependencies on the value of the "default"
|
||||
* iterator value.
|
||||
*
|
||||
* @return json_object_iterator
|
||||
*/
|
||||
struct json_object_iterator
|
||||
json_object_iter_init_default(void);
|
||||
|
||||
/** Retrieves an iterator to the first pair of the JSON Object.
|
||||
*
|
||||
* @warning Any modification of the underlying pair invalidates all
|
||||
* iterators to that pair.
|
||||
*
|
||||
* @param obj JSON Object instance (MUST be of type json_object)
|
||||
*
|
||||
* @return json_object_iterator If the JSON Object has at
|
||||
* least one pair, on return, the iterator refers
|
||||
* to the first pair. If the JSON Object doesn't
|
||||
* have any pairs, the returned iterator is
|
||||
* equivalent to the "end" iterator for the same
|
||||
* JSON Object instance.
|
||||
*
|
||||
* @code
|
||||
* struct json_object_iterator it;
|
||||
* struct json_object_iterator itEnd;
|
||||
* struct json_object* obj;
|
||||
*
|
||||
* obj = json_tokener_parse("{'first':'george', 'age':100}");
|
||||
* it = json_object_iter_begin(obj);
|
||||
* itEnd = json_object_iter_end(obj);
|
||||
*
|
||||
* while (!json_object_iter_equal(&it, &itEnd)) {
|
||||
* printf("%s\n",
|
||||
* json_object_iter_peek_name(&it));
|
||||
* json_object_iter_next(&it);
|
||||
* }
|
||||
*
|
||||
* @endcode
|
||||
*/
|
||||
struct json_object_iterator
|
||||
json_object_iter_begin(struct json_object* obj);
|
||||
|
||||
/** Retrieves the iterator that represents the position beyond the
|
||||
* last pair of the given JSON Object instance.
|
||||
*
|
||||
* @warning Do NOT write code that assumes that the "end"
|
||||
* iterator value is NULL, even if it is so in a
|
||||
* particular instance of the implementation.
|
||||
*
|
||||
* @note The reason we do not (and MUST NOT) provide
|
||||
* "json_object_iter_is_end(json_object_iterator* iter)"
|
||||
* type of API is because it would limit the underlying
|
||||
* representation of name/value containment (or force us
|
||||
* to add additional, otherwise unnecessary, fields to
|
||||
* the iterator structure). The "end" iterator and the
|
||||
* equality test method, on the other hand, permit us to
|
||||
* cleanly abstract pretty much any reasonable underlying
|
||||
* representation without burdening the iterator
|
||||
* structure with unnecessary data.
|
||||
*
|
||||
* @note For performance reasons, memorize the "end" iterator prior
|
||||
* to any loop.
|
||||
*
|
||||
* @param obj JSON Object instance (MUST be of type json_object)
|
||||
*
|
||||
* @return json_object_iterator On return, the iterator refers
|
||||
* to the "end" of the Object instance's pairs
|
||||
* (i.e., NOT the last pair, but "beyond the last
|
||||
* pair" value)
|
||||
*/
|
||||
struct json_object_iterator
|
||||
json_object_iter_end(const struct json_object* obj);
|
||||
|
||||
/** Returns an iterator to the next pair, if any
|
||||
*
|
||||
* @warning Any modification of the underlying pair
|
||||
* invalidates all iterators to that pair.
|
||||
*
|
||||
* @param iter [IN/OUT] Pointer to iterator that references a
|
||||
* name/value pair; MUST be a valid, non-end iterator.
|
||||
* WARNING: bad things will happen if invalid or "end"
|
||||
* iterator is passed. Upon return will contain the
|
||||
* reference to the next pair if there is one; if there
|
||||
* are no more pairs, will contain the "end" iterator
|
||||
* value, which may be compared against the return value
|
||||
* of json_object_iter_end() for the same JSON Object
|
||||
* instance.
|
||||
*/
|
||||
void
|
||||
json_object_iter_next(struct json_object_iterator* iter);
|
||||
|
||||
|
||||
/** Returns a const pointer to the name of the pair referenced
|
||||
* by the given iterator.
|
||||
*
|
||||
* @param iter pointer to iterator that references a name/value
|
||||
* pair; MUST be a valid, non-end iterator.
|
||||
*
|
||||
* @warning bad things will happen if an invalid or
|
||||
* "end" iterator is passed.
|
||||
*
|
||||
* @return const char* Pointer to the name of the referenced
|
||||
* name/value pair. The name memory belongs to the
|
||||
* name/value pair, will be freed when the pair is
|
||||
* deleted or modified, and MUST NOT be modified or
|
||||
* freed by the user.
|
||||
*/
|
||||
const char*
|
||||
json_object_iter_peek_name(const struct json_object_iterator* iter);
|
||||
|
||||
|
||||
/** Returns a pointer to the json-c instance representing the
|
||||
* value of the referenced name/value pair, without altering
|
||||
* the instance's reference count.
|
||||
*
|
||||
* @param iter pointer to iterator that references a name/value
|
||||
* pair; MUST be a valid, non-end iterator.
|
||||
*
|
||||
* @warning bad things will happen if invalid or
|
||||
* "end" iterator is passed.
|
||||
*
|
||||
* @return struct json_object* Pointer to the json-c value
|
||||
* instance of the referenced name/value pair; the
|
||||
* value's reference count is not changed by this
|
||||
* function: if you plan to hold on to this json-c node,
|
||||
* take a look at json_object_get() and
|
||||
* json_object_put(). IMPORTANT: json-c API represents
|
||||
* the JSON Null value as a NULL json_object instance
|
||||
* pointer.
|
||||
*/
|
||||
struct json_object*
|
||||
json_object_iter_peek_value(const struct json_object_iterator* iter);
|
||||
|
||||
|
||||
/** Tests two iterators for equality. Typically used to test
|
||||
* for end of iteration by comparing an iterator to the
|
||||
* corresponding "end" iterator (that was derived from the same
|
||||
* JSON Object instance).
|
||||
*
|
||||
* @note The reason we do not (and MUST NOT) provide
|
||||
* "json_object_iter_is_end(json_object_iterator* iter)"
|
||||
* type of API is because it would limit the underlying
|
||||
* representation of name/value containment (or force us
|
||||
* to add additional, otherwise unnecessary, fields to
|
||||
* the iterator structure). The equality test method, on
|
||||
* the other hand, permits us to cleanly abstract pretty
|
||||
* much any reasonable underlying representation.
|
||||
*
|
||||
* @param iter1 Pointer to first valid, non-NULL iterator
|
||||
* @param iter2 POinter to second valid, non-NULL iterator
|
||||
*
|
||||
* @warning if a NULL iterator pointer or an uninitialized
|
||||
* or invalid iterator, or iterators derived from
|
||||
* different JSON Object instances are passed, bad things
|
||||
* will happen!
|
||||
*
|
||||
* @return json_bool non-zero if iterators are equal (i.e., both
|
||||
* reference the same name/value pair or are both at
|
||||
* "end"); zero if they are not equal.
|
||||
*/
|
||||
json_bool
|
||||
json_object_iter_equal(const struct json_object_iterator* iter1,
|
||||
const struct json_object_iterator* iter2);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* JSON_OBJECT_ITERATOR_H */
|
||||
64
proxy_c/third-lib/json-c/src/json_object_private.h
Normal file
64
proxy_c/third-lib/json-c/src/json_object_private.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* $Id: json_object_private.h,v 1.4 2006/01/26 02:16:28 mclark Exp $
|
||||
*
|
||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||
* Michael Clark <michael@metaparadigm.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Do not use, json-c internal, may be changed or removed at any time.
|
||||
*/
|
||||
#ifndef _json_object_private_h_
|
||||
#define _json_object_private_h_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LEN_DIRECT_STRING_DATA 32 /**< how many bytes are directly stored in json_object for strings? */
|
||||
|
||||
typedef void (json_object_private_delete_fn)(struct json_object *o);
|
||||
|
||||
struct json_object
|
||||
{
|
||||
enum json_type o_type;
|
||||
json_object_private_delete_fn *_delete;
|
||||
json_object_to_json_string_fn *_to_json_string;
|
||||
uint_fast32_t _ref_count;
|
||||
struct printbuf *_pb;
|
||||
union data {
|
||||
json_bool c_boolean;
|
||||
double c_double;
|
||||
int64_t c_int64;
|
||||
struct lh_table *c_object;
|
||||
struct array_list *c_array;
|
||||
struct {
|
||||
union {
|
||||
/* optimize: if we have small strings, we can store them
|
||||
* directly. This saves considerable CPU cycles AND memory.
|
||||
*/
|
||||
char *ptr;
|
||||
char data[LEN_DIRECT_STRING_DATA];
|
||||
} str;
|
||||
int len;
|
||||
} c_string;
|
||||
} o;
|
||||
json_object_delete_fn *_user_delete;
|
||||
void *_userdata;
|
||||
};
|
||||
|
||||
void _json_c_set_last_err(const char *err_fmt, ...);
|
||||
|
||||
extern const char *json_number_chars;
|
||||
extern const char *json_hex_chars;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
327
proxy_c/third-lib/json-c/src/json_pointer.c
Normal file
327
proxy_c/third-lib/json-c/src/json_pointer.c
Normal file
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Alexandru Ardelean.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config_json_c.h"
|
||||
|
||||
#include "strerror_override.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "json_pointer.h"
|
||||
#include "strdup_compat.h"
|
||||
#include "vasprintf_compat.h"
|
||||
|
||||
/**
|
||||
* JavaScript Object Notation (JSON) Pointer
|
||||
* RFC 6901 - https://tools.ietf.org/html/rfc6901
|
||||
*/
|
||||
|
||||
static void string_replace_all_occurrences_with_char(char *s, const char *occur, char repl_char)
|
||||
{
|
||||
int slen = strlen(s);
|
||||
int skip = strlen(occur) - 1; /* length of the occurence, minus the char we're replacing */
|
||||
char *p = s;
|
||||
while ((p = strstr(p, occur))) {
|
||||
*p = repl_char;
|
||||
p++;
|
||||
slen -= skip;
|
||||
memmove(p, (p + skip), slen - (p - s) + 1); /* includes null char too */
|
||||
}
|
||||
}
|
||||
|
||||
static int is_valid_index(struct json_object *jo, const char *path, int32_t *idx)
|
||||
{
|
||||
int i, len = strlen(path);
|
||||
/* this code-path optimizes a bit, for when we reference the 0-9 index range in a JSON array
|
||||
and because leading zeros not allowed */
|
||||
if (len == 1) {
|
||||
if (isdigit((int)path[0])) {
|
||||
*idx = (path[0] - '0');
|
||||
goto check_oob;
|
||||
}
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
/* leading zeros not allowed per RFC */
|
||||
if (path[0] == '0') {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
/* RFC states base-10 decimals */
|
||||
for (i = 0; i < len; i++) {
|
||||
if (!isdigit((int)path[i])) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
*idx = strtol(path, NULL, 10);
|
||||
if (*idx < 0) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
check_oob:
|
||||
len = json_object_array_length(jo);
|
||||
if (*idx >= len) {
|
||||
errno = ENOENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int json_pointer_get_single_path(struct json_object *obj, char *path, struct json_object **value)
|
||||
{
|
||||
if (json_object_is_type(obj, json_type_array)) {
|
||||
int32_t idx;
|
||||
if (!is_valid_index(obj, path, &idx))
|
||||
return -1;
|
||||
obj = json_object_array_get_idx(obj, idx);
|
||||
if (obj) {
|
||||
if (value)
|
||||
*value = obj;
|
||||
return 0;
|
||||
}
|
||||
/* Entry not found */
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* RFC states that we first must eval all ~1 then all ~0 */
|
||||
string_replace_all_occurrences_with_char(path, "~1", '/');
|
||||
string_replace_all_occurrences_with_char(path, "~0", '~');
|
||||
|
||||
if (!json_object_object_get_ex(obj, path, value)) {
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int json_pointer_set_single_path(
|
||||
struct json_object *parent,
|
||||
const char *path,
|
||||
struct json_object *value)
|
||||
{
|
||||
if (json_object_is_type(parent, json_type_array)) {
|
||||
int32_t idx;
|
||||
/* RFC (Chapter 4) states that '-' may be used to add new elements to an array */
|
||||
if (path[0] == '-' && path[1] == '\0')
|
||||
return json_object_array_add(parent, value);
|
||||
if (!is_valid_index(parent, path, &idx))
|
||||
return -1;
|
||||
return json_object_array_put_idx(parent, idx, value);
|
||||
}
|
||||
|
||||
/* path replacements should have been done in json_pointer_get_single_path(),
|
||||
and we should still be good here */
|
||||
if (json_object_is_type(parent, json_type_object))
|
||||
return json_object_object_add(parent, path, value);
|
||||
|
||||
/* Getting here means that we tried to "dereference" a primitive JSON type (like string, int, bool).
|
||||
i.e. add a sub-object to it */
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int json_pointer_get_recursive(
|
||||
struct json_object *obj,
|
||||
char *path,
|
||||
struct json_object **value)
|
||||
{
|
||||
char *endp;
|
||||
int rc;
|
||||
|
||||
/* All paths (on each recursion level must have a leading '/' */
|
||||
if (path[0] != '/') {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
path++;
|
||||
|
||||
endp = strchr(path, '/');
|
||||
if (endp)
|
||||
*endp = '\0';
|
||||
|
||||
/* If we err-ed here, return here */
|
||||
if ((rc = json_pointer_get_single_path(obj, path, &obj)))
|
||||
return rc;
|
||||
|
||||
if (endp) {
|
||||
*endp = '/'; /* Put the slash back, so that the sanity check passes on next recursion level */
|
||||
return json_pointer_get_recursive(obj, endp, value);
|
||||
}
|
||||
|
||||
/* We should be at the end of the recursion here */
|
||||
if (value)
|
||||
*value = obj;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int json_pointer_get(struct json_object *obj, const char *path, struct json_object **res)
|
||||
{
|
||||
char *path_copy = NULL;
|
||||
int rc;
|
||||
|
||||
if (!obj || !path) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (path[0] == '\0') {
|
||||
if (res)
|
||||
*res = obj;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* pass a working copy to the recursive call */
|
||||
if (!(path_copy = strdup(path))) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
rc = json_pointer_get_recursive(obj, path_copy, res);
|
||||
free(path_copy);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int json_pointer_getf(struct json_object *obj, struct json_object **res, const char *path_fmt, ...)
|
||||
{
|
||||
char *path_copy = NULL;
|
||||
int rc = 0;
|
||||
va_list args;
|
||||
|
||||
if (!obj || !path_fmt) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
va_start(args, path_fmt);
|
||||
rc = vasprintf(&path_copy, path_fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (path_copy[0] == '\0') {
|
||||
if (res)
|
||||
*res = obj;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = json_pointer_get_recursive(obj, path_copy, res);
|
||||
out:
|
||||
free(path_copy);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int json_pointer_set(struct json_object **obj, const char *path, struct json_object *value)
|
||||
{
|
||||
const char *endp;
|
||||
char *path_copy = NULL;
|
||||
struct json_object *set = NULL;
|
||||
int rc;
|
||||
|
||||
if (!obj || !path) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (path[0] == '\0') {
|
||||
json_object_put(*obj);
|
||||
*obj = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (path[0] != '/') {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If there's only 1 level to set, stop here */
|
||||
if ((endp = strrchr(path, '/')) == path) {
|
||||
path++;
|
||||
return json_pointer_set_single_path(*obj, path, value);
|
||||
}
|
||||
|
||||
/* pass a working copy to the recursive call */
|
||||
if (!(path_copy = strdup(path))) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
path_copy[endp - path] = '\0';
|
||||
rc = json_pointer_get_recursive(*obj, path_copy, &set);
|
||||
free(path_copy);
|
||||
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
endp++;
|
||||
return json_pointer_set_single_path(set, endp, value);
|
||||
}
|
||||
|
||||
int json_pointer_setf(struct json_object **obj, struct json_object *value, const char *path_fmt, ...)
|
||||
{
|
||||
char *endp;
|
||||
char *path_copy = NULL;
|
||||
struct json_object *set = NULL;
|
||||
va_list args;
|
||||
int rc = 0;
|
||||
|
||||
if (!obj || !path_fmt) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* pass a working copy to the recursive call */
|
||||
va_start(args, path_fmt);
|
||||
rc = vasprintf(&path_copy, path_fmt, args);
|
||||
va_end(args);
|
||||
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (path_copy[0] == '\0') {
|
||||
json_object_put(*obj);
|
||||
*obj = value;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (path_copy[0] != '/') {
|
||||
errno = EINVAL;
|
||||
rc = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* If there's only 1 level to set, stop here */
|
||||
if ((endp = strrchr(path_copy, '/')) == path_copy) {
|
||||
set = *obj;
|
||||
goto set_single_path;
|
||||
}
|
||||
|
||||
*endp = '\0';
|
||||
rc = json_pointer_get_recursive(*obj, path_copy, &set);
|
||||
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
set_single_path:
|
||||
endp++;
|
||||
rc = json_pointer_set_single_path(set, endp, value);
|
||||
out:
|
||||
free(path_copy);
|
||||
return rc;
|
||||
}
|
||||
|
||||
120
proxy_c/third-lib/json-c/src/json_pointer.h
Normal file
120
proxy_c/third-lib/json-c/src/json_pointer.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Alexadru Ardelean.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief JSON Pointer (RFC 6901) implementation for retrieving
|
||||
* objects from a json-c object tree.
|
||||
*/
|
||||
#ifndef _json_pointer_h_
|
||||
#define _json_pointer_h_
|
||||
|
||||
#include "json_object.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Retrieves a JSON sub-object from inside another JSON object
|
||||
* using the JSON pointer notation as defined in RFC 6901
|
||||
* https://tools.ietf.org/html/rfc6901
|
||||
*
|
||||
* The returned JSON sub-object is equivalent to parsing manually the
|
||||
* 'obj' JSON tree ; i.e. it's not a new object that is created, but rather
|
||||
* a pointer inside the JSON tree.
|
||||
*
|
||||
* Internally, this is equivalent to doing a series of 'json_object_object_get()'
|
||||
* and 'json_object_array_get_idx()' along the given 'path'.
|
||||
*
|
||||
* Note that the 'path' string supports 'printf()' type arguments, so, whatever
|
||||
* is added after the 'res' param will be treated as an argument for 'path'
|
||||
* Example: json_pointer_get(obj, "/foo/%d/%s", &res, 0, bar)
|
||||
* This means, that you need to escape '%' with '%%' (just like in printf())
|
||||
*
|
||||
* @param obj the json_object instance/tree from where to retrieve sub-objects
|
||||
* @param path a (RFC6901) string notation for the sub-object to retrieve
|
||||
* @param res a pointer where to store a reference to the json_object
|
||||
* associated with the given path
|
||||
*
|
||||
* @return negative if an error (or not found), or 0 if succeeded
|
||||
*/
|
||||
int json_pointer_get(struct json_object *obj, const char *path, struct json_object **res);
|
||||
|
||||
/**
|
||||
* This is a variant of 'json_pointer_get()' that supports printf() style arguments.
|
||||
*
|
||||
* Example: json_pointer_getf(obj, res, "/foo/%d/%s", 0, bak)
|
||||
* This also means that you need to escape '%' with '%%' (just like in printf())
|
||||
*
|
||||
* Please take into consideration all recommended 'printf()' format security
|
||||
* aspects when using this function.
|
||||
*
|
||||
* @param obj the json_object instance/tree to which to add a sub-object
|
||||
* @param res a pointer where to store a reference to the json_object
|
||||
* associated with the given path
|
||||
* @param path_fmt a printf() style format for the path
|
||||
*
|
||||
* @return negative if an error (or not found), or 0 if succeeded
|
||||
*/
|
||||
int json_pointer_getf(struct json_object *obj, struct json_object **res, const char *path_fmt, ...);
|
||||
|
||||
/**
|
||||
* Sets JSON object 'value' in the 'obj' tree at the location specified
|
||||
* by the 'path'. 'path' is JSON pointer notation as defined in RFC 6901
|
||||
* https://tools.ietf.org/html/rfc6901
|
||||
*
|
||||
* Note that 'obj' is a double pointer, mostly for the "" (empty string)
|
||||
* case, where the entire JSON object would be replaced by 'value'.
|
||||
* In the case of the "" path, the object at '*obj' will have it's refcount
|
||||
* decremented with 'json_object_put()' and the 'value' object will be assigned to it.
|
||||
*
|
||||
* For other cases (JSON sub-objects) ownership of 'value' will be transferred into
|
||||
* '*obj' via 'json_object_object_add()' & 'json_object_array_put_idx()', so the
|
||||
* only time the refcount should be decremented for 'value' is when the return value of
|
||||
* 'json_pointer_set()' is negative (meaning the 'value' object did not get set into '*obj').
|
||||
*
|
||||
* That also implies that 'json_pointer_set()' does not do any refcount incrementing.
|
||||
* (Just that single decrement that was mentioned above).
|
||||
*
|
||||
* Note that the 'path' string supports 'printf()' type arguments, so, whatever
|
||||
* is added after the 'value' param will be treated as an argument for 'path'
|
||||
* Example: json_pointer_set(obj, "/foo/%d/%s", value, 0, bak)
|
||||
* This means, that you need to escape '%' with '%%' (just like in printf())
|
||||
*
|
||||
* @param obj the json_object instance/tree to which to add a sub-object
|
||||
* @param path a (RFC6901) string notation for the sub-object to set in the tree
|
||||
* @param value object to set at path
|
||||
*
|
||||
* @return negative if an error (or not found), or 0 if succeeded
|
||||
*/
|
||||
int json_pointer_set(struct json_object **obj, const char *path, struct json_object *value);
|
||||
|
||||
/**
|
||||
* This is a variant of 'json_pointer_set()' that supports printf() style arguments.
|
||||
*
|
||||
* Example: json_pointer_setf(obj, value, "/foo/%d/%s", 0, bak)
|
||||
* This also means that you need to escape '%' with '%%' (just like in printf())
|
||||
*
|
||||
* Please take into consideration all recommended 'printf()' format security
|
||||
* aspects when using this function.
|
||||
*
|
||||
* @param obj the json_object instance/tree to which to add a sub-object
|
||||
* @param value object to set at path
|
||||
* @param path_fmt a printf() style format for the path
|
||||
*
|
||||
* @return negative if an error (or not found), or 0 if succeeded
|
||||
*/
|
||||
int json_pointer_setf(struct json_object **obj, struct json_object *value, const char *path_fmt, ...);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
997
proxy_c/third-lib/json-c/src/json_tokener.c
Normal file
997
proxy_c/third-lib/json-c/src/json_tokener.c
Normal file
@@ -0,0 +1,997 @@
|
||||
/*
|
||||
* $Id: json_tokener.c,v 1.20 2006/07/25 03:24:50 mclark Exp $
|
||||
*
|
||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||
* Michael Clark <michael@metaparadigm.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 2008-2009 Yahoo! Inc. All rights reserved.
|
||||
* The copyrights to the contents of this file are licensed under the MIT License
|
||||
* (http://www.opensource.org/licenses/mit-license.php)
|
||||
*/
|
||||
|
||||
#include "config_json_c.h"
|
||||
|
||||
#include <math.h>
|
||||
#include "math_compat.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "printbuf.h"
|
||||
#include "arraylist.h"
|
||||
#include "json_inttypes.h"
|
||||
#include "json_object.h"
|
||||
#include "json_object_private.h"
|
||||
#include "json_tokener.h"
|
||||
#include "json_util.h"
|
||||
#include "strdup_compat.h"
|
||||
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif /* HAVE_LOCALE_H */
|
||||
#ifdef HAVE_XLOCALE_H
|
||||
#include <xlocale.h>
|
||||
#endif
|
||||
|
||||
#define jt_hexdigit(x) (((x) <= '9') ? (x) - '0' : ((x) & 7) + 9)
|
||||
|
||||
#if !HAVE_STRNCASECMP && defined(_MSC_VER)
|
||||
/* MSC has the version as _strnicmp */
|
||||
# define strncasecmp _strnicmp
|
||||
#elif !HAVE_STRNCASECMP
|
||||
# error You do not have strncasecmp on your system.
|
||||
#endif /* HAVE_STRNCASECMP */
|
||||
|
||||
/* Use C99 NAN by default; if not available, nan("") should work too. */
|
||||
#ifndef NAN
|
||||
#define NAN nan("")
|
||||
#endif /* !NAN */
|
||||
|
||||
static const char json_null_str[] = "null";
|
||||
static const int json_null_str_len = sizeof(json_null_str) - 1;
|
||||
static const char json_inf_str[] = "Infinity";
|
||||
static const char json_inf_str_lower[] = "infinity";
|
||||
static const unsigned int json_inf_str_len = sizeof(json_inf_str) - 1;
|
||||
static const char json_nan_str[] = "NaN";
|
||||
static const int json_nan_str_len = sizeof(json_nan_str) - 1;
|
||||
static const char json_true_str[] = "true";
|
||||
static const int json_true_str_len = sizeof(json_true_str) - 1;
|
||||
static const char json_false_str[] = "false";
|
||||
static const int json_false_str_len = sizeof(json_false_str) - 1;
|
||||
|
||||
static const char* json_tokener_errors[] = {
|
||||
"success",
|
||||
"continue",
|
||||
"nesting too deep",
|
||||
"unexpected end of data",
|
||||
"unexpected character",
|
||||
"null expected",
|
||||
"boolean expected",
|
||||
"number expected",
|
||||
"array value separator ',' expected",
|
||||
"quoted object property name expected",
|
||||
"object property name separator ':' expected",
|
||||
"object value separator ',' expected",
|
||||
"invalid string sequence",
|
||||
"expected comment",
|
||||
"buffer size overflow"
|
||||
};
|
||||
|
||||
const char *json_tokener_error_desc(enum json_tokener_error jerr)
|
||||
{
|
||||
int jerr_int = (int) jerr;
|
||||
if (jerr_int < 0 ||
|
||||
jerr_int >= (int)(sizeof(json_tokener_errors) / sizeof(json_tokener_errors[0])))
|
||||
return "Unknown error, "
|
||||
"invalid json_tokener_error value passed to json_tokener_error_desc()";
|
||||
return json_tokener_errors[jerr];
|
||||
}
|
||||
|
||||
enum json_tokener_error json_tokener_get_error(struct json_tokener *tok)
|
||||
{
|
||||
return tok->err;
|
||||
}
|
||||
|
||||
/* Stuff for decoding unicode sequences */
|
||||
#define IS_HIGH_SURROGATE(uc) (((uc) & 0xFC00) == 0xD800)
|
||||
#define IS_LOW_SURROGATE(uc) (((uc) & 0xFC00) == 0xDC00)
|
||||
#define DECODE_SURROGATE_PAIR(hi,lo) ((((hi) & 0x3FF) << 10) + ((lo) & 0x3FF) + 0x10000)
|
||||
static unsigned char utf8_replacement_char[3] = { 0xEF, 0xBF, 0xBD };
|
||||
|
||||
struct json_tokener* json_tokener_new_ex(int depth)
|
||||
{
|
||||
struct json_tokener *tok;
|
||||
|
||||
tok = (struct json_tokener*)calloc(1, sizeof(struct json_tokener));
|
||||
if (!tok) return NULL;
|
||||
tok->stack = (struct json_tokener_srec *) calloc(depth,
|
||||
sizeof(struct json_tokener_srec));
|
||||
if (!tok->stack) {
|
||||
free(tok);
|
||||
return NULL;
|
||||
}
|
||||
tok->pb = printbuf_new();
|
||||
tok->max_depth = depth;
|
||||
json_tokener_reset(tok);
|
||||
return tok;
|
||||
}
|
||||
|
||||
struct json_tokener* json_tokener_new(void)
|
||||
{
|
||||
return json_tokener_new_ex(JSON_TOKENER_DEFAULT_DEPTH);
|
||||
}
|
||||
|
||||
void json_tokener_free(struct json_tokener *tok)
|
||||
{
|
||||
json_tokener_reset(tok);
|
||||
if (tok->pb) printbuf_free(tok->pb);
|
||||
free(tok->stack);
|
||||
free(tok);
|
||||
}
|
||||
|
||||
static void json_tokener_reset_level(struct json_tokener *tok, int depth)
|
||||
{
|
||||
tok->stack[depth].state = json_tokener_state_eatws;
|
||||
tok->stack[depth].saved_state = json_tokener_state_start;
|
||||
json_object_put(tok->stack[depth].current);
|
||||
tok->stack[depth].current = NULL;
|
||||
free(tok->stack[depth].obj_field_name);
|
||||
tok->stack[depth].obj_field_name = NULL;
|
||||
}
|
||||
|
||||
void json_tokener_reset(struct json_tokener *tok)
|
||||
{
|
||||
int i;
|
||||
if (!tok)
|
||||
return;
|
||||
|
||||
for(i = tok->depth; i >= 0; i--)
|
||||
json_tokener_reset_level(tok, i);
|
||||
tok->depth = 0;
|
||||
tok->err = json_tokener_success;
|
||||
}
|
||||
|
||||
struct json_object* json_tokener_parse(const char *str)
|
||||
{
|
||||
enum json_tokener_error jerr_ignored;
|
||||
struct json_object* obj;
|
||||
obj = json_tokener_parse_verbose(str, &jerr_ignored);
|
||||
return obj;
|
||||
}
|
||||
|
||||
struct json_object* json_tokener_parse_verbose(const char *str,
|
||||
enum json_tokener_error *error)
|
||||
{
|
||||
struct json_tokener* tok;
|
||||
struct json_object* obj;
|
||||
|
||||
tok = json_tokener_new();
|
||||
if (!tok)
|
||||
return NULL;
|
||||
obj = json_tokener_parse_ex(tok, str, -1);
|
||||
*error = tok->err;
|
||||
if(tok->err != json_tokener_success) {
|
||||
if (obj != NULL)
|
||||
json_object_put(obj);
|
||||
obj = NULL;
|
||||
}
|
||||
|
||||
json_tokener_free(tok);
|
||||
return obj;
|
||||
}
|
||||
|
||||
#define state tok->stack[tok->depth].state
|
||||
#define saved_state tok->stack[tok->depth].saved_state
|
||||
#define current tok->stack[tok->depth].current
|
||||
#define obj_field_name tok->stack[tok->depth].obj_field_name
|
||||
|
||||
/* Optimization:
|
||||
* json_tokener_parse_ex() consumed a lot of CPU in its main loop,
|
||||
* iterating character-by character. A large performance boost is
|
||||
* achieved by using tighter loops to locally handle units such as
|
||||
* comments and strings. Loops that handle an entire token within
|
||||
* their scope also gather entire strings and pass them to
|
||||
* printbuf_memappend() in a single call, rather than calling
|
||||
* printbuf_memappend() one char at a time.
|
||||
*
|
||||
* PEEK_CHAR() and ADVANCE_CHAR() macros are used for code that is
|
||||
* common to both the main loop and the tighter loops.
|
||||
*/
|
||||
|
||||
/* PEEK_CHAR(dest, tok) macro:
|
||||
* Peeks at the current char and stores it in dest.
|
||||
* Returns 1 on success, sets tok->err and returns 0 if no more chars.
|
||||
* Implicit inputs: str, len vars
|
||||
*/
|
||||
#define PEEK_CHAR(dest, tok) \
|
||||
(((tok)->char_offset == len) ? \
|
||||
(((tok)->depth == 0 && \
|
||||
state == json_tokener_state_eatws && \
|
||||
saved_state == json_tokener_state_finish \
|
||||
) ? \
|
||||
(((tok)->err = json_tokener_success), 0) \
|
||||
: \
|
||||
(((tok)->err = json_tokener_continue), 0) \
|
||||
) : \
|
||||
(((dest) = *str), 1) \
|
||||
)
|
||||
|
||||
/* ADVANCE_CHAR() macro:
|
||||
* Incrementes str & tok->char_offset.
|
||||
* For convenience of existing conditionals, returns the old value of c (0 on eof)
|
||||
* Implicit inputs: c var
|
||||
*/
|
||||
#define ADVANCE_CHAR(str, tok) \
|
||||
( ++(str), ((tok)->char_offset)++, c)
|
||||
|
||||
|
||||
/* End optimization macro defs */
|
||||
|
||||
|
||||
struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
||||
const char *str, int len)
|
||||
{
|
||||
struct json_object *obj = NULL;
|
||||
char c = '\1';
|
||||
#ifdef HAVE_USELOCALE
|
||||
locale_t oldlocale = uselocale(NULL);
|
||||
locale_t newloc;
|
||||
#elif defined(HAVE_SETLOCALE)
|
||||
char *oldlocale = NULL;
|
||||
#endif
|
||||
|
||||
tok->char_offset = 0;
|
||||
tok->err = json_tokener_success;
|
||||
|
||||
/* this interface is presently not 64-bit clean due to the int len argument
|
||||
and the internal printbuf interface that takes 32-bit int len arguments
|
||||
so the function limits the maximum string size to INT32_MAX (2GB).
|
||||
If the function is called with len == -1 then strlen is called to check
|
||||
the string length is less than INT32_MAX (2GB) */
|
||||
if ((len < -1) || (len == -1 && strlen(str) > INT32_MAX)) {
|
||||
tok->err = json_tokener_error_size;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_USELOCALE
|
||||
{
|
||||
locale_t duploc = duplocale(oldlocale);
|
||||
newloc = newlocale(LC_NUMERIC, "C", duploc);
|
||||
// XXX at least Debian 8.4 has a bug in newlocale where it doesn't
|
||||
// change the decimal separator unless you set LC_TIME!
|
||||
if (newloc)
|
||||
{
|
||||
duploc = newloc; // original duploc has been freed by newlocale()
|
||||
newloc = newlocale(LC_TIME, "C", duploc);
|
||||
}
|
||||
if (newloc == NULL)
|
||||
{
|
||||
freelocale(duploc);
|
||||
return NULL;
|
||||
}
|
||||
uselocale(newloc);
|
||||
}
|
||||
#elif defined(HAVE_SETLOCALE)
|
||||
{
|
||||
char *tmplocale;
|
||||
tmplocale = setlocale(LC_NUMERIC, NULL);
|
||||
if (tmplocale) oldlocale = strdup(tmplocale);
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
}
|
||||
#endif
|
||||
|
||||
while (PEEK_CHAR(c, tok)) {
|
||||
|
||||
redo_char:
|
||||
switch(state) {
|
||||
|
||||
case json_tokener_state_eatws:
|
||||
/* Advance until we change state */
|
||||
while (isspace((int)c)) {
|
||||
if ((!ADVANCE_CHAR(str, tok)) || (!PEEK_CHAR(c, tok)))
|
||||
goto out;
|
||||
}
|
||||
if(c == '/' && !(tok->flags & JSON_TOKENER_STRICT)) {
|
||||
printbuf_reset(tok->pb);
|
||||
printbuf_memappend_fast(tok->pb, &c, 1);
|
||||
state = json_tokener_state_comment_start;
|
||||
} else {
|
||||
state = saved_state;
|
||||
goto redo_char;
|
||||
}
|
||||
break;
|
||||
|
||||
case json_tokener_state_start:
|
||||
switch(c) {
|
||||
case '{':
|
||||
state = json_tokener_state_eatws;
|
||||
saved_state = json_tokener_state_object_field_start;
|
||||
current = json_object_new_object();
|
||||
if(current == NULL)
|
||||
goto out;
|
||||
break;
|
||||
case '[':
|
||||
state = json_tokener_state_eatws;
|
||||
saved_state = json_tokener_state_array;
|
||||
current = json_object_new_array();
|
||||
if(current == NULL)
|
||||
goto out;
|
||||
break;
|
||||
case 'I':
|
||||
case 'i':
|
||||
state = json_tokener_state_inf;
|
||||
printbuf_reset(tok->pb);
|
||||
tok->st_pos = 0;
|
||||
goto redo_char;
|
||||
case 'N':
|
||||
case 'n':
|
||||
state = json_tokener_state_null; // or NaN
|
||||
printbuf_reset(tok->pb);
|
||||
tok->st_pos = 0;
|
||||
goto redo_char;
|
||||
case '\'':
|
||||
if (tok->flags & JSON_TOKENER_STRICT) {
|
||||
/* in STRICT mode only double-quote are allowed */
|
||||
tok->err = json_tokener_error_parse_unexpected;
|
||||
goto out;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
case '"':
|
||||
state = json_tokener_state_string;
|
||||
printbuf_reset(tok->pb);
|
||||
tok->quote_char = c;
|
||||
break;
|
||||
case 'T':
|
||||
case 't':
|
||||
case 'F':
|
||||
case 'f':
|
||||
state = json_tokener_state_boolean;
|
||||
printbuf_reset(tok->pb);
|
||||
tok->st_pos = 0;
|
||||
goto redo_char;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '-':
|
||||
state = json_tokener_state_number;
|
||||
printbuf_reset(tok->pb);
|
||||
tok->is_double = 0;
|
||||
goto redo_char;
|
||||
default:
|
||||
tok->err = json_tokener_error_parse_unexpected;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
|
||||
case json_tokener_state_finish:
|
||||
if(tok->depth == 0) goto out;
|
||||
obj = json_object_get(current);
|
||||
json_tokener_reset_level(tok, tok->depth);
|
||||
tok->depth--;
|
||||
goto redo_char;
|
||||
|
||||
case json_tokener_state_inf: /* aka starts with 'i' (or 'I', or "-i", or "-I") */
|
||||
{
|
||||
/* If we were guaranteed to have len set, then we could (usually) handle
|
||||
* the entire "Infinity" check in a single strncmp (strncasecmp), but
|
||||
* since len might be -1 (i.e. "read until \0"), we need to check it
|
||||
* a character at a time.
|
||||
* Trying to handle it both ways would make this code considerably more
|
||||
* complicated with likely little performance benefit.
|
||||
*/
|
||||
int is_negative = 0;
|
||||
const char *_json_inf_str = json_inf_str;
|
||||
if (!(tok->flags & JSON_TOKENER_STRICT))
|
||||
_json_inf_str = json_inf_str_lower;
|
||||
|
||||
/* Note: tok->st_pos must be 0 when state is set to json_tokener_state_inf */
|
||||
while (tok->st_pos < (int)json_inf_str_len)
|
||||
{
|
||||
char inf_char = *str;
|
||||
if (!(tok->flags & JSON_TOKENER_STRICT))
|
||||
inf_char = tolower((int)*str);
|
||||
if (inf_char != _json_inf_str[tok->st_pos])
|
||||
{
|
||||
tok->err = json_tokener_error_parse_unexpected;
|
||||
goto out;
|
||||
}
|
||||
tok->st_pos++;
|
||||
(void)ADVANCE_CHAR(str, tok);
|
||||
if (!PEEK_CHAR(c, tok))
|
||||
{
|
||||
/* out of input chars, for now at least */
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
/* We checked the full length of "Infinity", so create the object.
|
||||
* When handling -Infinity, the number parsing code will have dropped
|
||||
* the "-" into tok->pb for us, so check it now.
|
||||
*/
|
||||
if (printbuf_length(tok->pb) > 0 && *(tok->pb->buf) == '-')
|
||||
{
|
||||
is_negative = 1;
|
||||
}
|
||||
current = json_object_new_double(is_negative
|
||||
? -INFINITY : INFINITY);
|
||||
if (current == NULL)
|
||||
goto out;
|
||||
saved_state = json_tokener_state_finish;
|
||||
state = json_tokener_state_eatws;
|
||||
goto redo_char;
|
||||
|
||||
}
|
||||
break;
|
||||
case json_tokener_state_null: /* aka starts with 'n' */
|
||||
{
|
||||
int size;
|
||||
int size_nan;
|
||||
printbuf_memappend_fast(tok->pb, &c, 1);
|
||||
size = json_min(tok->st_pos+1, json_null_str_len);
|
||||
size_nan = json_min(tok->st_pos+1, json_nan_str_len);
|
||||
if((!(tok->flags & JSON_TOKENER_STRICT) &&
|
||||
strncasecmp(json_null_str, tok->pb->buf, size) == 0)
|
||||
|| (strncmp(json_null_str, tok->pb->buf, size) == 0)
|
||||
) {
|
||||
if (tok->st_pos == json_null_str_len) {
|
||||
current = NULL;
|
||||
saved_state = json_tokener_state_finish;
|
||||
state = json_tokener_state_eatws;
|
||||
goto redo_char;
|
||||
}
|
||||
}
|
||||
else if ((!(tok->flags & JSON_TOKENER_STRICT) &&
|
||||
strncasecmp(json_nan_str, tok->pb->buf, size_nan) == 0) ||
|
||||
(strncmp(json_nan_str, tok->pb->buf, size_nan) == 0)
|
||||
)
|
||||
{
|
||||
if (tok->st_pos == json_nan_str_len)
|
||||
{
|
||||
current = json_object_new_double(NAN);
|
||||
if (current == NULL)
|
||||
goto out;
|
||||
saved_state = json_tokener_state_finish;
|
||||
state = json_tokener_state_eatws;
|
||||
goto redo_char;
|
||||
}
|
||||
} else {
|
||||
tok->err = json_tokener_error_parse_null;
|
||||
goto out;
|
||||
}
|
||||
tok->st_pos++;
|
||||
}
|
||||
break;
|
||||
|
||||
case json_tokener_state_comment_start:
|
||||
if(c == '*') {
|
||||
state = json_tokener_state_comment;
|
||||
} else if(c == '/') {
|
||||
state = json_tokener_state_comment_eol;
|
||||
} else {
|
||||
tok->err = json_tokener_error_parse_comment;
|
||||
goto out;
|
||||
}
|
||||
printbuf_memappend_fast(tok->pb, &c, 1);
|
||||
break;
|
||||
|
||||
case json_tokener_state_comment:
|
||||
{
|
||||
/* Advance until we change state */
|
||||
const char *case_start = str;
|
||||
while(c != '*') {
|
||||
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
||||
printbuf_memappend_fast(tok->pb, case_start, str-case_start);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
printbuf_memappend_fast(tok->pb, case_start, 1+str-case_start);
|
||||
state = json_tokener_state_comment_end;
|
||||
}
|
||||
break;
|
||||
|
||||
case json_tokener_state_comment_eol:
|
||||
{
|
||||
/* Advance until we change state */
|
||||
const char *case_start = str;
|
||||
while(c != '\n') {
|
||||
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
||||
printbuf_memappend_fast(tok->pb, case_start, str-case_start);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
printbuf_memappend_fast(tok->pb, case_start, str-case_start);
|
||||
MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
|
||||
state = json_tokener_state_eatws;
|
||||
}
|
||||
break;
|
||||
|
||||
case json_tokener_state_comment_end:
|
||||
printbuf_memappend_fast(tok->pb, &c, 1);
|
||||
if(c == '/') {
|
||||
MC_DEBUG("json_tokener_comment: %s\n", tok->pb->buf);
|
||||
state = json_tokener_state_eatws;
|
||||
} else {
|
||||
state = json_tokener_state_comment;
|
||||
}
|
||||
break;
|
||||
|
||||
case json_tokener_state_string:
|
||||
{
|
||||
/* Advance until we change state */
|
||||
const char *case_start = str;
|
||||
while(1) {
|
||||
if(c == tok->quote_char) {
|
||||
printbuf_memappend_fast(tok->pb, case_start, str-case_start);
|
||||
current = json_object_new_string_len(tok->pb->buf, tok->pb->bpos);
|
||||
if(current == NULL)
|
||||
goto out;
|
||||
saved_state = json_tokener_state_finish;
|
||||
state = json_tokener_state_eatws;
|
||||
break;
|
||||
} else if(c == '\\') {
|
||||
printbuf_memappend_fast(tok->pb, case_start, str-case_start);
|
||||
saved_state = json_tokener_state_string;
|
||||
state = json_tokener_state_string_escape;
|
||||
break;
|
||||
}
|
||||
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
||||
printbuf_memappend_fast(tok->pb, case_start, str-case_start);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case json_tokener_state_string_escape:
|
||||
switch(c) {
|
||||
case '"':
|
||||
case '\\':
|
||||
case '/':
|
||||
printbuf_memappend_fast(tok->pb, &c, 1);
|
||||
state = saved_state;
|
||||
break;
|
||||
case 'b':
|
||||
case 'n':
|
||||
case 'r':
|
||||
case 't':
|
||||
case 'f':
|
||||
if(c == 'b') printbuf_memappend_fast(tok->pb, "\b", 1);
|
||||
else if(c == 'n') printbuf_memappend_fast(tok->pb, "\n", 1);
|
||||
else if(c == 'r') printbuf_memappend_fast(tok->pb, "\r", 1);
|
||||
else if(c == 't') printbuf_memappend_fast(tok->pb, "\t", 1);
|
||||
else if(c == 'f') printbuf_memappend_fast(tok->pb, "\f", 1);
|
||||
state = saved_state;
|
||||
break;
|
||||
case 'u':
|
||||
tok->ucs_char = 0;
|
||||
tok->st_pos = 0;
|
||||
state = json_tokener_state_escape_unicode;
|
||||
break;
|
||||
default:
|
||||
tok->err = json_tokener_error_parse_string;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
|
||||
case json_tokener_state_escape_unicode:
|
||||
{
|
||||
unsigned int got_hi_surrogate = 0;
|
||||
|
||||
/* Handle a 4-byte sequence, or two sequences if a surrogate pair */
|
||||
while(1) {
|
||||
if (c && strchr(json_hex_chars, c)) {
|
||||
tok->ucs_char += ((unsigned int)jt_hexdigit(c) << ((3-tok->st_pos++)*4));
|
||||
if(tok->st_pos == 4) {
|
||||
unsigned char unescaped_utf[4];
|
||||
|
||||
if (got_hi_surrogate) {
|
||||
if (IS_LOW_SURROGATE(tok->ucs_char)) {
|
||||
/* Recalculate the ucs_char, then fall thru to process normally */
|
||||
tok->ucs_char = DECODE_SURROGATE_PAIR(got_hi_surrogate, tok->ucs_char);
|
||||
} else {
|
||||
/* Hi surrogate was not followed by a low surrogate */
|
||||
/* Replace the hi and process the rest normally */
|
||||
printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
|
||||
}
|
||||
got_hi_surrogate = 0;
|
||||
}
|
||||
|
||||
if (tok->ucs_char < 0x80) {
|
||||
unescaped_utf[0] = tok->ucs_char;
|
||||
printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 1);
|
||||
} else if (tok->ucs_char < 0x800) {
|
||||
unescaped_utf[0] = 0xc0 | (tok->ucs_char >> 6);
|
||||
unescaped_utf[1] = 0x80 | (tok->ucs_char & 0x3f);
|
||||
printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 2);
|
||||
} else if (IS_HIGH_SURROGATE(tok->ucs_char)) {
|
||||
/* Got a high surrogate. Remember it and look for the
|
||||
* the beginning of another sequence, which should be the
|
||||
* low surrogate.
|
||||
*/
|
||||
got_hi_surrogate = tok->ucs_char;
|
||||
/* Not at end, and the next two chars should be "\u" */
|
||||
if ((len == -1 || len > (tok->char_offset + 2)) &&
|
||||
// str[0] != '0' && // implied by json_hex_chars, above.
|
||||
(str[1] == '\\') &&
|
||||
(str[2] == 'u'))
|
||||
{
|
||||
/* Advance through the 16 bit surrogate, and move on to the
|
||||
* next sequence. The next step is to process the following
|
||||
* characters.
|
||||
*/
|
||||
if( !ADVANCE_CHAR(str, tok) || !ADVANCE_CHAR(str, tok) ) {
|
||||
printbuf_memappend_fast(tok->pb,
|
||||
(char*) utf8_replacement_char, 3);
|
||||
}
|
||||
/* Advance to the first char of the next sequence and
|
||||
* continue processing with the next sequence.
|
||||
*/
|
||||
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
||||
printbuf_memappend_fast(tok->pb,
|
||||
(char*) utf8_replacement_char, 3);
|
||||
goto out;
|
||||
}
|
||||
tok->ucs_char = 0;
|
||||
tok->st_pos = 0;
|
||||
continue; /* other json_tokener_state_escape_unicode */
|
||||
} else {
|
||||
/* Got a high surrogate without another sequence following
|
||||
* it. Put a replacement char in for the hi surrogate
|
||||
* and pretend we finished.
|
||||
*/
|
||||
printbuf_memappend_fast(tok->pb,
|
||||
(char*) utf8_replacement_char, 3);
|
||||
}
|
||||
} else if (IS_LOW_SURROGATE(tok->ucs_char)) {
|
||||
/* Got a low surrogate not preceded by a high */
|
||||
printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
|
||||
} else if (tok->ucs_char < 0x10000) {
|
||||
unescaped_utf[0] = 0xe0 | (tok->ucs_char >> 12);
|
||||
unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
|
||||
unescaped_utf[2] = 0x80 | (tok->ucs_char & 0x3f);
|
||||
printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 3);
|
||||
} else if (tok->ucs_char < 0x110000) {
|
||||
unescaped_utf[0] = 0xf0 | ((tok->ucs_char >> 18) & 0x07);
|
||||
unescaped_utf[1] = 0x80 | ((tok->ucs_char >> 12) & 0x3f);
|
||||
unescaped_utf[2] = 0x80 | ((tok->ucs_char >> 6) & 0x3f);
|
||||
unescaped_utf[3] = 0x80 | (tok->ucs_char & 0x3f);
|
||||
printbuf_memappend_fast(tok->pb, (char*)unescaped_utf, 4);
|
||||
} else {
|
||||
/* Don't know what we got--insert the replacement char */
|
||||
printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
|
||||
}
|
||||
state = saved_state;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
tok->err = json_tokener_error_parse_string;
|
||||
goto out;
|
||||
}
|
||||
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
||||
if (got_hi_surrogate) /* Clean up any pending chars */
|
||||
printbuf_memappend_fast(tok->pb, (char*)utf8_replacement_char, 3);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case json_tokener_state_boolean:
|
||||
{
|
||||
int size1, size2;
|
||||
printbuf_memappend_fast(tok->pb, &c, 1);
|
||||
size1 = json_min(tok->st_pos+1, json_true_str_len);
|
||||
size2 = json_min(tok->st_pos+1, json_false_str_len);
|
||||
if((!(tok->flags & JSON_TOKENER_STRICT) &&
|
||||
strncasecmp(json_true_str, tok->pb->buf, size1) == 0)
|
||||
|| (strncmp(json_true_str, tok->pb->buf, size1) == 0)
|
||||
) {
|
||||
if(tok->st_pos == json_true_str_len) {
|
||||
current = json_object_new_boolean(1);
|
||||
if(current == NULL)
|
||||
goto out;
|
||||
saved_state = json_tokener_state_finish;
|
||||
state = json_tokener_state_eatws;
|
||||
goto redo_char;
|
||||
}
|
||||
} else if((!(tok->flags & JSON_TOKENER_STRICT) &&
|
||||
strncasecmp(json_false_str, tok->pb->buf, size2) == 0)
|
||||
|| (strncmp(json_false_str, tok->pb->buf, size2) == 0)) {
|
||||
if(tok->st_pos == json_false_str_len) {
|
||||
current = json_object_new_boolean(0);
|
||||
if(current == NULL)
|
||||
goto out;
|
||||
saved_state = json_tokener_state_finish;
|
||||
state = json_tokener_state_eatws;
|
||||
goto redo_char;
|
||||
}
|
||||
} else {
|
||||
tok->err = json_tokener_error_parse_boolean;
|
||||
goto out;
|
||||
}
|
||||
tok->st_pos++;
|
||||
}
|
||||
break;
|
||||
|
||||
case json_tokener_state_number:
|
||||
{
|
||||
/* Advance until we change state */
|
||||
const char *case_start = str;
|
||||
int case_len=0;
|
||||
int is_exponent=0;
|
||||
int negativesign_next_possible_location=1;
|
||||
while(c && strchr(json_number_chars, c)) {
|
||||
++case_len;
|
||||
|
||||
/* non-digit characters checks */
|
||||
/* note: since the main loop condition to get here was
|
||||
an input starting with 0-9 or '-', we are
|
||||
protected from input starting with '.' or
|
||||
e/E. */
|
||||
if (c == '.') {
|
||||
if (tok->is_double != 0) {
|
||||
/* '.' can only be found once, and out of the exponent part.
|
||||
Thus, if the input is already flagged as double, it
|
||||
is invalid. */
|
||||
tok->err = json_tokener_error_parse_number;
|
||||
goto out;
|
||||
}
|
||||
tok->is_double = 1;
|
||||
}
|
||||
if (c == 'e' || c == 'E') {
|
||||
if (is_exponent != 0) {
|
||||
/* only one exponent possible */
|
||||
tok->err = json_tokener_error_parse_number;
|
||||
goto out;
|
||||
}
|
||||
is_exponent = 1;
|
||||
tok->is_double = 1;
|
||||
/* the exponent part can begin with a negative sign */
|
||||
negativesign_next_possible_location = case_len + 1;
|
||||
}
|
||||
if (c == '-' && case_len != negativesign_next_possible_location) {
|
||||
/* If the negative sign is not where expected (ie
|
||||
start of input or start of exponent part), the
|
||||
input is invalid. */
|
||||
tok->err = json_tokener_error_parse_number;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
||||
printbuf_memappend_fast(tok->pb, case_start, case_len);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (case_len>0)
|
||||
printbuf_memappend_fast(tok->pb, case_start, case_len);
|
||||
|
||||
// Check for -Infinity
|
||||
if (tok->pb->buf[0] == '-' && case_len <= 1 &&
|
||||
(c == 'i' || c == 'I'))
|
||||
{
|
||||
state = json_tokener_state_inf;
|
||||
tok->st_pos = 0;
|
||||
goto redo_char;
|
||||
}
|
||||
}
|
||||
{
|
||||
int64_t num64;
|
||||
double numd;
|
||||
if (!tok->is_double && json_parse_int64(tok->pb->buf, &num64) == 0) {
|
||||
if (num64 && tok->pb->buf[0]=='0' &&
|
||||
(tok->flags & JSON_TOKENER_STRICT)) {
|
||||
/* in strict mode, number must not start with 0 */
|
||||
tok->err = json_tokener_error_parse_number;
|
||||
goto out;
|
||||
}
|
||||
current = json_object_new_int64(num64);
|
||||
if(current == NULL)
|
||||
goto out;
|
||||
}
|
||||
else if(tok->is_double && json_parse_double(tok->pb->buf, &numd) == 0)
|
||||
{
|
||||
current = json_object_new_double_s(numd, tok->pb->buf);
|
||||
if(current == NULL)
|
||||
goto out;
|
||||
} else {
|
||||
tok->err = json_tokener_error_parse_number;
|
||||
goto out;
|
||||
}
|
||||
saved_state = json_tokener_state_finish;
|
||||
state = json_tokener_state_eatws;
|
||||
goto redo_char;
|
||||
}
|
||||
break;
|
||||
|
||||
case json_tokener_state_array_after_sep:
|
||||
case json_tokener_state_array:
|
||||
if(c == ']') {
|
||||
if (state == json_tokener_state_array_after_sep &&
|
||||
(tok->flags & JSON_TOKENER_STRICT))
|
||||
{
|
||||
tok->err = json_tokener_error_parse_unexpected;
|
||||
goto out;
|
||||
}
|
||||
saved_state = json_tokener_state_finish;
|
||||
state = json_tokener_state_eatws;
|
||||
} else {
|
||||
if(tok->depth >= tok->max_depth-1) {
|
||||
tok->err = json_tokener_error_depth;
|
||||
goto out;
|
||||
}
|
||||
state = json_tokener_state_array_add;
|
||||
tok->depth++;
|
||||
json_tokener_reset_level(tok, tok->depth);
|
||||
goto redo_char;
|
||||
}
|
||||
break;
|
||||
|
||||
case json_tokener_state_array_add:
|
||||
if( json_object_array_add(current, obj) != 0 )
|
||||
goto out;
|
||||
saved_state = json_tokener_state_array_sep;
|
||||
state = json_tokener_state_eatws;
|
||||
goto redo_char;
|
||||
|
||||
case json_tokener_state_array_sep:
|
||||
if(c == ']') {
|
||||
saved_state = json_tokener_state_finish;
|
||||
state = json_tokener_state_eatws;
|
||||
} else if(c == ',') {
|
||||
saved_state = json_tokener_state_array_after_sep;
|
||||
state = json_tokener_state_eatws;
|
||||
} else {
|
||||
tok->err = json_tokener_error_parse_array;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
|
||||
case json_tokener_state_object_field_start:
|
||||
case json_tokener_state_object_field_start_after_sep:
|
||||
if(c == '}') {
|
||||
if (state == json_tokener_state_object_field_start_after_sep &&
|
||||
(tok->flags & JSON_TOKENER_STRICT))
|
||||
{
|
||||
tok->err = json_tokener_error_parse_unexpected;
|
||||
goto out;
|
||||
}
|
||||
saved_state = json_tokener_state_finish;
|
||||
state = json_tokener_state_eatws;
|
||||
} else if (c == '"' || c == '\'') {
|
||||
tok->quote_char = c;
|
||||
printbuf_reset(tok->pb);
|
||||
state = json_tokener_state_object_field;
|
||||
} else {
|
||||
tok->err = json_tokener_error_parse_object_key_name;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
|
||||
case json_tokener_state_object_field:
|
||||
{
|
||||
/* Advance until we change state */
|
||||
const char *case_start = str;
|
||||
while(1) {
|
||||
if(c == tok->quote_char) {
|
||||
printbuf_memappend_fast(tok->pb, case_start, str-case_start);
|
||||
obj_field_name = strdup(tok->pb->buf);
|
||||
saved_state = json_tokener_state_object_field_end;
|
||||
state = json_tokener_state_eatws;
|
||||
break;
|
||||
} else if(c == '\\') {
|
||||
printbuf_memappend_fast(tok->pb, case_start, str-case_start);
|
||||
saved_state = json_tokener_state_object_field;
|
||||
state = json_tokener_state_string_escape;
|
||||
break;
|
||||
}
|
||||
if (!ADVANCE_CHAR(str, tok) || !PEEK_CHAR(c, tok)) {
|
||||
printbuf_memappend_fast(tok->pb, case_start, str-case_start);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case json_tokener_state_object_field_end:
|
||||
if(c == ':') {
|
||||
saved_state = json_tokener_state_object_value;
|
||||
state = json_tokener_state_eatws;
|
||||
} else {
|
||||
tok->err = json_tokener_error_parse_object_key_sep;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
|
||||
case json_tokener_state_object_value:
|
||||
if(tok->depth >= tok->max_depth-1) {
|
||||
tok->err = json_tokener_error_depth;
|
||||
goto out;
|
||||
}
|
||||
state = json_tokener_state_object_value_add;
|
||||
tok->depth++;
|
||||
json_tokener_reset_level(tok, tok->depth);
|
||||
goto redo_char;
|
||||
|
||||
case json_tokener_state_object_value_add:
|
||||
json_object_object_add(current, obj_field_name, obj);
|
||||
free(obj_field_name);
|
||||
obj_field_name = NULL;
|
||||
saved_state = json_tokener_state_object_sep;
|
||||
state = json_tokener_state_eatws;
|
||||
goto redo_char;
|
||||
|
||||
case json_tokener_state_object_sep:
|
||||
/* { */
|
||||
if(c == '}') {
|
||||
saved_state = json_tokener_state_finish;
|
||||
state = json_tokener_state_eatws;
|
||||
} else if(c == ',') {
|
||||
saved_state = json_tokener_state_object_field_start_after_sep;
|
||||
state = json_tokener_state_eatws;
|
||||
} else {
|
||||
tok->err = json_tokener_error_parse_object_value_sep;
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
if (!ADVANCE_CHAR(str, tok))
|
||||
goto out;
|
||||
} /* while(PEEK_CHAR) */
|
||||
|
||||
out:
|
||||
if (c &&
|
||||
(state == json_tokener_state_finish) &&
|
||||
(tok->depth == 0) &&
|
||||
(tok->flags & JSON_TOKENER_STRICT)) {
|
||||
/* unexpected char after JSON data */
|
||||
tok->err = json_tokener_error_parse_unexpected;
|
||||
}
|
||||
if (!c) { /* We hit an eof char (0) */
|
||||
if(state != json_tokener_state_finish &&
|
||||
saved_state != json_tokener_state_finish)
|
||||
tok->err = json_tokener_error_parse_eof;
|
||||
}
|
||||
|
||||
#ifdef HAVE_USELOCALE
|
||||
uselocale(oldlocale);
|
||||
freelocale(newloc);
|
||||
#elif defined(HAVE_SETLOCALE)
|
||||
setlocale(LC_NUMERIC, oldlocale);
|
||||
free(oldlocale);
|
||||
#endif
|
||||
|
||||
if (tok->err == json_tokener_success)
|
||||
{
|
||||
json_object *ret = json_object_get(current);
|
||||
int ii;
|
||||
|
||||
/* Partially reset, so we parse additional objects on subsequent calls. */
|
||||
for(ii = tok->depth; ii >= 0; ii--)
|
||||
json_tokener_reset_level(tok, ii);
|
||||
return ret;
|
||||
}
|
||||
|
||||
MC_DEBUG("json_tokener_parse_ex: error %s at offset %d\n",
|
||||
json_tokener_errors[tok->err], tok->char_offset);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void json_tokener_set_flags(struct json_tokener *tok, int flags)
|
||||
{
|
||||
tok->flags = flags;
|
||||
}
|
||||
216
proxy_c/third-lib/json-c/src/json_tokener.h
Normal file
216
proxy_c/third-lib/json-c/src/json_tokener.h
Normal file
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* $Id: json_tokener.h,v 1.10 2006/07/25 03:24:50 mclark Exp $
|
||||
*
|
||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||
* Michael Clark <michael@metaparadigm.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Methods to parse an input string into a tree of json_object objects.
|
||||
*/
|
||||
#ifndef _json_tokener_h_
|
||||
#define _json_tokener_h_
|
||||
|
||||
#include <stddef.h>
|
||||
#include "json_object.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum json_tokener_error {
|
||||
json_tokener_success,
|
||||
json_tokener_continue,
|
||||
json_tokener_error_depth,
|
||||
json_tokener_error_parse_eof,
|
||||
json_tokener_error_parse_unexpected,
|
||||
json_tokener_error_parse_null,
|
||||
json_tokener_error_parse_boolean,
|
||||
json_tokener_error_parse_number,
|
||||
json_tokener_error_parse_array,
|
||||
json_tokener_error_parse_object_key_name,
|
||||
json_tokener_error_parse_object_key_sep,
|
||||
json_tokener_error_parse_object_value_sep,
|
||||
json_tokener_error_parse_string,
|
||||
json_tokener_error_parse_comment,
|
||||
json_tokener_error_size
|
||||
};
|
||||
|
||||
enum json_tokener_state {
|
||||
json_tokener_state_eatws,
|
||||
json_tokener_state_start,
|
||||
json_tokener_state_finish,
|
||||
json_tokener_state_null,
|
||||
json_tokener_state_comment_start,
|
||||
json_tokener_state_comment,
|
||||
json_tokener_state_comment_eol,
|
||||
json_tokener_state_comment_end,
|
||||
json_tokener_state_string,
|
||||
json_tokener_state_string_escape,
|
||||
json_tokener_state_escape_unicode,
|
||||
json_tokener_state_boolean,
|
||||
json_tokener_state_number,
|
||||
json_tokener_state_array,
|
||||
json_tokener_state_array_add,
|
||||
json_tokener_state_array_sep,
|
||||
json_tokener_state_object_field_start,
|
||||
json_tokener_state_object_field,
|
||||
json_tokener_state_object_field_end,
|
||||
json_tokener_state_object_value,
|
||||
json_tokener_state_object_value_add,
|
||||
json_tokener_state_object_sep,
|
||||
json_tokener_state_array_after_sep,
|
||||
json_tokener_state_object_field_start_after_sep,
|
||||
json_tokener_state_inf
|
||||
};
|
||||
|
||||
struct json_tokener_srec
|
||||
{
|
||||
enum json_tokener_state state, saved_state;
|
||||
struct json_object *obj;
|
||||
struct json_object *current;
|
||||
char *obj_field_name;
|
||||
};
|
||||
|
||||
#define JSON_TOKENER_DEFAULT_DEPTH 32
|
||||
|
||||
struct json_tokener
|
||||
{
|
||||
char *str;
|
||||
struct printbuf *pb;
|
||||
int max_depth, depth, is_double, st_pos, char_offset;
|
||||
enum json_tokener_error err;
|
||||
unsigned int ucs_char;
|
||||
char quote_char;
|
||||
struct json_tokener_srec *stack;
|
||||
int flags;
|
||||
};
|
||||
/**
|
||||
* @deprecated Unused in json-c code
|
||||
*/
|
||||
typedef struct json_tokener json_tokener;
|
||||
|
||||
/**
|
||||
* Be strict when parsing JSON input. Use caution with
|
||||
* this flag as what is considered valid may become more
|
||||
* restrictive from one release to the next, causing your
|
||||
* code to fail on previously working input.
|
||||
*
|
||||
* This flag is not set by default.
|
||||
*
|
||||
* @see json_tokener_set_flags()
|
||||
*/
|
||||
#define JSON_TOKENER_STRICT 0x01
|
||||
|
||||
/**
|
||||
* Given an error previously returned by json_tokener_get_error(),
|
||||
* return a human readable description of the error.
|
||||
*
|
||||
* @return a generic error message is returned if an invalid error value is provided.
|
||||
*/
|
||||
const char *json_tokener_error_desc(enum json_tokener_error jerr);
|
||||
|
||||
/**
|
||||
* Retrieve the error caused by the last call to json_tokener_parse_ex(),
|
||||
* or json_tokener_success if there is no error.
|
||||
*
|
||||
* When parsing a JSON string in pieces, if the tokener is in the middle
|
||||
* of parsing this will return json_tokener_continue.
|
||||
*
|
||||
* See also json_tokener_error_desc().
|
||||
*/
|
||||
JSON_EXPORT enum json_tokener_error json_tokener_get_error(struct json_tokener *tok);
|
||||
|
||||
JSON_EXPORT struct json_tokener* json_tokener_new(void);
|
||||
JSON_EXPORT struct json_tokener* json_tokener_new_ex(int depth);
|
||||
JSON_EXPORT void json_tokener_free(struct json_tokener *tok);
|
||||
JSON_EXPORT void json_tokener_reset(struct json_tokener *tok);
|
||||
JSON_EXPORT struct json_object* json_tokener_parse(const char *str);
|
||||
JSON_EXPORT struct json_object* json_tokener_parse_verbose(const char *str, enum json_tokener_error *error);
|
||||
|
||||
/**
|
||||
* Set flags that control how parsing will be done.
|
||||
*/
|
||||
JSON_EXPORT void json_tokener_set_flags(struct json_tokener *tok, int flags);
|
||||
|
||||
/**
|
||||
* Parse a string and return a non-NULL json_object if a valid JSON value
|
||||
* is found. The string does not need to be a JSON object or array;
|
||||
* it can also be a string, number or boolean value.
|
||||
*
|
||||
* A partial JSON string can be parsed. If the parsing is incomplete,
|
||||
* NULL will be returned and json_tokener_get_error() will return
|
||||
* json_tokener_continue.
|
||||
* json_tokener_parse_ex() can then be called with additional bytes in str
|
||||
* to continue the parsing.
|
||||
*
|
||||
* If json_tokener_parse_ex() returns NULL and the error is anything other than
|
||||
* json_tokener_continue, a fatal error has occurred and parsing must be
|
||||
* halted. Then, the tok object must not be reused until json_tokener_reset() is
|
||||
* called.
|
||||
*
|
||||
* When a valid JSON value is parsed, a non-NULL json_object will be
|
||||
* returned. Also, json_tokener_get_error() will return json_tokener_success.
|
||||
* Be sure to check the type with json_object_is_type() or
|
||||
* json_object_get_type() before using the object.
|
||||
*
|
||||
* @b XXX this shouldn't use internal fields:
|
||||
* Trailing characters after the parsed value do not automatically cause an
|
||||
* error. It is up to the caller to decide whether to treat this as an
|
||||
* error or to handle the additional characters, perhaps by parsing another
|
||||
* json value starting from that point.
|
||||
*
|
||||
* Extra characters can be detected by comparing the tok->char_offset against
|
||||
* the length of the last len parameter passed in.
|
||||
*
|
||||
* The tokener does \b not maintain an internal buffer so the caller is
|
||||
* responsible for calling json_tokener_parse_ex with an appropriate str
|
||||
* parameter starting with the extra characters.
|
||||
*
|
||||
* This interface is presently not 64-bit clean due to the int len argument
|
||||
* so the function limits the maximum string size to INT32_MAX (2GB).
|
||||
* If the function is called with len == -1 then strlen is called to check
|
||||
* the string length is less than INT32_MAX (2GB)
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
json_object *jobj = NULL;
|
||||
const char *mystring = NULL;
|
||||
int stringlen = 0;
|
||||
enum json_tokener_error jerr;
|
||||
do {
|
||||
mystring = ... // get JSON string, e.g. read from file, etc...
|
||||
stringlen = strlen(mystring);
|
||||
jobj = json_tokener_parse_ex(tok, mystring, stringlen);
|
||||
} while ((jerr = json_tokener_get_error(tok)) == json_tokener_continue);
|
||||
if (jerr != json_tokener_success)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", json_tokener_error_desc(jerr));
|
||||
// Handle errors, as appropriate for your application.
|
||||
}
|
||||
if (tok->char_offset < stringlen) // XXX shouldn't access internal fields
|
||||
{
|
||||
// Handle extra characters after parsed object as desired.
|
||||
// e.g. issue an error, parse another object from that point, etc...
|
||||
}
|
||||
// Success, use jobj here.
|
||||
|
||||
@endcode
|
||||
*
|
||||
* @param tok a json_tokener previously allocated with json_tokener_new()
|
||||
* @param str an string with any valid JSON expression, or portion of. This does not need to be null terminated.
|
||||
* @param len the length of str
|
||||
*/
|
||||
JSON_EXPORT struct json_object* json_tokener_parse_ex(struct json_tokener *tok,
|
||||
const char *str, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
243
proxy_c/third-lib/json-c/src/json_util.c
Normal file
243
proxy_c/third-lib/json-c/src/json_util.c
Normal file
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* $Id: json_util.c,v 1.4 2006/01/30 23:07:57 mclark Exp $
|
||||
*
|
||||
* Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
|
||||
* Michael Clark <michael@metaparadigm.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the MIT license. See COPYING for details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config_json_c.h"
|
||||
#undef realloc
|
||||
|
||||
#include "strerror_override.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif /* HAVE_SYS_TYPES_H */
|
||||
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif /* HAVE_SYS_STAT_H */
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif /* HAVE_FCNTL_H */
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
|
||||
#ifdef WIN32
|
||||
# if MSC_VER < 1800
|
||||
/* strtoll is available only since Visual Studio 2013 */
|
||||
# define strtoll _strtoi64
|
||||
# endif
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
# include <io.h>
|
||||
#endif /* defined(WIN32) */
|
||||
|
||||
#if !defined(HAVE_OPEN) && defined(WIN32)
|
||||
# define open _open
|
||||
#endif
|
||||
|
||||
#include "snprintf_compat.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "printbuf.h"
|
||||
#include "json_inttypes.h"
|
||||
#include "json_object.h"
|
||||
#include "json_tokener.h"
|
||||
#include "json_util.h"
|
||||
|
||||
static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const char *filename);
|
||||
|
||||
static char _last_err[256] = "";
|
||||
|
||||
const char *json_util_get_last_err()
|
||||
{
|
||||
if (_last_err[0] == '\0')
|
||||
return NULL;
|
||||
return _last_err;
|
||||
}
|
||||
|
||||
void _json_c_set_last_err(const char *err_fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, err_fmt);
|
||||
// Ignore (attempted) overruns from snprintf
|
||||
(void)vsnprintf(_last_err, sizeof(_last_err), err_fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
struct json_object* json_object_from_fd(int fd)
|
||||
{
|
||||
struct printbuf *pb;
|
||||
struct json_object *obj;
|
||||
char buf[JSON_FILE_BUF_SIZE];
|
||||
int ret;
|
||||
|
||||
if(!(pb = printbuf_new())) {
|
||||
_json_c_set_last_err("json_object_from_file: printbuf_new failed\n");
|
||||
return NULL;
|
||||
}
|
||||
while((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) {
|
||||
printbuf_memappend(pb, buf, ret);
|
||||
}
|
||||
if(ret < 0) {
|
||||
_json_c_set_last_err("json_object_from_fd: error reading fd %d: %s\n", fd, strerror(errno));
|
||||
printbuf_free(pb);
|
||||
return NULL;
|
||||
}
|
||||
obj = json_tokener_parse(pb->buf);
|
||||
printbuf_free(pb);
|
||||
return obj;
|
||||
}
|
||||
|
||||
struct json_object* json_object_from_file(const char *filename)
|
||||
{
|
||||
struct json_object *obj;
|
||||
int fd;
|
||||
|
||||
if((fd = open(filename, O_RDONLY)) < 0) {
|
||||
_json_c_set_last_err("json_object_from_file: error opening file %s: %s\n",
|
||||
filename, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
obj = json_object_from_fd(fd);
|
||||
close(fd);
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* extended "format and write to file" function */
|
||||
|
||||
int json_object_to_file_ext(const char *filename, struct json_object *obj, int flags)
|
||||
{
|
||||
int fd, ret;
|
||||
int saved_errno;
|
||||
|
||||
if (!obj) {
|
||||
_json_c_set_last_err("json_object_to_file: object is null\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) {
|
||||
_json_c_set_last_err("json_object_to_file: error opening file %s: %s\n",
|
||||
filename, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
ret = _json_object_to_fd(fd, obj, flags, filename);
|
||||
saved_errno = errno;
|
||||
close(fd);
|
||||
errno = saved_errno;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int json_object_to_fd(int fd, struct json_object *obj, int flags)
|
||||
{
|
||||
if (!obj) {
|
||||
_json_c_set_last_err("json_object_to_fd: object is null\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _json_object_to_fd(fd, obj, flags, NULL);
|
||||
}
|
||||
static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const char *filename)
|
||||
{
|
||||
int ret;
|
||||
const char *json_str;
|
||||
unsigned int wpos, wsize;
|
||||
|
||||
filename = filename ? filename : "(fd)";
|
||||
|
||||
if (!(json_str = json_object_to_json_string_ext(obj,flags))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */
|
||||
wpos = 0;
|
||||
while(wpos < wsize) {
|
||||
if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) {
|
||||
_json_c_set_last_err("json_object_to_file: error writing file %s: %s\n",
|
||||
filename, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* because of the above check for ret < 0, we can safely cast and add */
|
||||
wpos += (unsigned int)ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// backwards compatible "format and write to file" function
|
||||
|
||||
int json_object_to_file(const char *filename, struct json_object *obj)
|
||||
{
|
||||
return json_object_to_file_ext(filename, obj, JSON_C_TO_STRING_PLAIN);
|
||||
}
|
||||
|
||||
int json_parse_double(const char *buf, double *retval)
|
||||
{
|
||||
char *end;
|
||||
*retval = strtod(buf, &end);
|
||||
return end == buf ? 1 : 0;
|
||||
}
|
||||
|
||||
int json_parse_int64(const char *buf, int64_t *retval)
|
||||
{
|
||||
char *end = NULL;
|
||||
int64_t val;
|
||||
|
||||
errno = 0;
|
||||
val = strtoll(buf, &end, 10);
|
||||
if (end != buf)
|
||||
*retval = val;
|
||||
return ((val == 0 && errno != 0) || (end == buf)) ? 1 : 0;
|
||||
}
|
||||
|
||||
#ifndef HAVE_REALLOC
|
||||
void* rpl_realloc(void* p, size_t n)
|
||||
{
|
||||
if (n == 0)
|
||||
n = 1;
|
||||
if (p == 0)
|
||||
return malloc(n);
|
||||
return realloc(p, n);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define NELEM(a) (sizeof(a) / sizeof(a[0]))
|
||||
static const char* json_type_name[] = {
|
||||
/* If you change this, be sure to update the enum json_type definition too */
|
||||
"null",
|
||||
"boolean",
|
||||
"double",
|
||||
"int",
|
||||
"object",
|
||||
"array",
|
||||
"string",
|
||||
};
|
||||
|
||||
const char *json_type_to_name(enum json_type o_type)
|
||||
{
|
||||
int o_type_int = (int)o_type;
|
||||
if (o_type_int < 0 || o_type_int >= (int)NELEM(json_type_name))
|
||||
{
|
||||
_json_c_set_last_err("json_type_to_name: type %d is out of range [0,%d]\n", o_type, NELEM(json_type_name));
|
||||
return NULL;
|
||||
}
|
||||
return json_type_name[o_type];
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user