git-svn-id: http://svn.openzap.org/svn/openzap/trunk@288 a93c3328-9c30-0410-af19-c9cd2b2d52af
This commit is contained in:
Anthony Minessale 2007-06-23 18:51:10 +00:00
parent dbc918f44b
commit e1dc87d541
10 changed files with 210 additions and 47 deletions

View File

@ -119,7 +119,7 @@ testtones: $(SRC)/testtones.c $(MYLIB)
$(CC) $(INCS) -L. $(SRC)/testtones.c -o testtones -lopenzap -lm -lpthread
testisdn: $(SRC)/testisdn.c $(MYLIB)
$(CC) $(INCS) -L. $(SRC)/testisdn.c -o testisdn -lopenzap -lm -lpthread
$(CC) $(INCS) $(ZAP_CFLAGS) -L. $(SRC)/testisdn.c -o testisdn -lopenzap -lm -lpthread
testanalog: $(SRC)/testanalog.c $(MYLIB)
$(CC) $(INCS) -L. $(SRC)/testanalog.c -o testanalog -lopenzap -lm -lpthread

View File

@ -83,7 +83,7 @@ WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = .. ../include ../isdn ../isdn/include
INPUT = ../src ../src/include ../src/isdn ../src/isdn/include
FILE_PATTERNS = *.c \
*.cc \
*.cxx \

View File

@ -174,6 +174,11 @@
#define zap_test_flag(obj, flag) ((obj)->flags & flag)
#define zap_test_pflag(obj, flag) ((obj)->pflags & flag)
#define zap_set_alarm_flag(obj, flag) (obj)->alarm_flags |= (flag)
#define zap_clear_alarm_flag(obj, flag) (obj)->alarm_flags &= ~(flag)
#define zap_test_alarm_flag(obj, flag) ((obj)->alarm_flags & flag)
/*!
\brief Set a flag on an arbitrary object
\command obj the object to set the flags on
@ -324,6 +329,7 @@ struct zap_channel {
zap_socket_t sockfd;
zap_channel_flag_t flags;
uint32_t pflags;
zap_alarm_flag_t alarm_flags;
zap_channel_feature_t features;
zap_codec_t effective_codec;
zap_codec_t native_codec;
@ -423,7 +429,8 @@ struct zap_io_interface {
zio_configure_t configure;
zio_open_t open;
zio_close_t close;
zio_destroy_channel_t destroy_channel;
zio_channel_destroy_t channel_destroy;
zio_get_alarms_t get_alarms;
zio_command_t command;
zio_wait_t wait;
zio_read_t read;
@ -465,6 +472,7 @@ zap_status_t zap_channel_outgoing_call(zap_channel_t *zchan);
void zap_channel_rotate_tokens(zap_channel_t *zchan);
void zap_channel_clear_detected_tones(zap_channel_t *zchan);
void zap_channel_clear_needed_tones(zap_channel_t *zchan);
zap_status_t zap_channel_get_alarms(zap_channel_t *zchan);
zap_status_t zap_channel_send_fsk_data(zap_channel_t *zchan, zap_fsk_data_state_t *fsk_data, float db_level);
zap_status_t zap_channel_clear_token(zap_channel_t *zchan, const char *token);
zap_status_t zap_channel_add_token(zap_channel_t *zchan, char *token, int end);

View File

@ -138,12 +138,24 @@ typedef enum {
ZAP_OOB_FLASH,
ZAP_OOB_RING_START,
ZAP_OOB_RING_STOP,
ZAP_OOB_ALARM_TRAP,
ZAP_OOB_ALARM_CLEAR,
ZAP_OOB_NOOP,
ZAP_OOB_INVALID
} zap_oob_event_t;
#define OOB_STRINGS "DTMF", "ONHOOK", "OFFHOOK", "WINK", "FLASH", "RING_START", "RING_STOP", "NOOP", "INVALID"
#define OOB_STRINGS "DTMF", "ONHOOK", "OFFHOOK", "WINK", "FLASH", "RING_START", "RING_STOP", "ALARM_TRAP", "ALARM_CLEAR", "NOOP", "INVALID"
ZAP_STR2ENUM_P(zap_str2zap_oob_event, zap_oob_event2str, zap_oob_event_t)
typedef enum {
ZAP_ALARM_NONE = 0,
ZAP_ALARM_RECOVER = (1 << 0),
ZAP_ALARM_LOOPBACK = (1 << 2),
ZAP_ALARM_YELLOW = (1 << 3),
ZAP_ALARM_RED = (1 << 4),
ZAP_ALARM_BLUE = (1 << 5),
ZAP_ALARM_NOTOPEN = ( 1 << 6)
} zap_alarm_flag_t;
typedef enum {
ZAP_SIGTYPE_NONE,
ZAP_SIGTYPE_ISDN,
@ -162,10 +174,13 @@ typedef enum {
ZAP_SIGEVENT_PROGRESS_MEDIA,
ZAP_SIGEVENT_NOTIFY,
ZAP_SIGEVENT_TONE_DETECTED,
ZAP_SIGEVENT_ALARM_TRAP,
ZAP_SIGEVENT_ALARM_CLEAR,
ZAP_SIGEVENT_MISC,
ZAP_SIGEVENT_INVALID
} zap_signal_event_t;
#define SIGNAL_STRINGS "START", "STOP", "TRANSFER", "ANSWER", "UP", "FLASH", "PROGRESS", "PROGRESS_MEDIA", "NOTIFY", "TONE_DETECTED", "MISC", "INVALID"
#define SIGNAL_STRINGS "START", "STOP", "TRANSFER", "ANSWER", "UP", "FLASH", "PROGRESS", \
"PROGRESS_MEDIA", "NOTIFY", "TONE_DETECTED", "ALARM_TRAP", "ALARM_CLEAR", "MISC", "INVALID"
ZAP_STR2ENUM_P(zap_str2zap_signal_event, zap_signal_event2str, zap_signal_event_t)
typedef enum {
@ -322,9 +337,10 @@ typedef struct zap_span zap_span_t;
#define ZIO_CONFIGURE_ARGS (const char *category, const char *var, const char *val, int lineno)
#define ZIO_OPEN_ARGS (zap_channel_t *zchan)
#define ZIO_CLOSE_ARGS (zap_channel_t *zchan)
#define ZIO_DESTROY_CHANNEL_ARGS (zap_channel_t *zchan)
#define ZIO_CHANNEL_DESTROY_ARGS (zap_channel_t *zchan)
#define ZIO_COMMAND_ARGS (zap_channel_t *zchan, zap_command_t command, void *obj)
#define ZIO_WAIT_ARGS (zap_channel_t *zchan, zap_wait_flag_t *flags, int32_t to)
#define ZIO_GET_ALARMS_ARGS (zap_channel_t *zchan)
#define ZIO_READ_ARGS (zap_channel_t *zchan, void *data, zap_size_t *datalen)
#define ZIO_WRITE_ARGS (zap_channel_t *zchan, void *data, zap_size_t *datalen)
@ -338,7 +354,8 @@ typedef zap_status_t (*zio_configure_span_t) ZIO_CONFIGURE_SPAN_ARGS ;
typedef zap_status_t (*zio_configure_t) ZIO_CONFIGURE_ARGS ;
typedef zap_status_t (*zio_open_t) ZIO_OPEN_ARGS ;
typedef zap_status_t (*zio_close_t) ZIO_CLOSE_ARGS ;
typedef zap_status_t (*zio_destroy_channel_t) ZIO_DESTROY_CHANNEL_ARGS ;
typedef zap_status_t (*zio_channel_destroy_t) ZIO_CHANNEL_DESTROY_ARGS ;
typedef zap_status_t (*zio_get_alarms_t) ZIO_GET_ALARMS_ARGS ;
typedef zap_status_t (*zio_command_t) ZIO_COMMAND_ARGS ;
typedef zap_status_t (*zio_wait_t) ZIO_WAIT_ARGS ;
typedef zap_status_t (*zio_read_t) ZIO_READ_ARGS ;
@ -354,7 +371,8 @@ typedef zap_status_t (*zio_write_t) ZIO_WRITE_ARGS ;
#define ZIO_CONFIGURE_FUNCTION(name) zap_status_t name ZIO_CONFIGURE_ARGS
#define ZIO_OPEN_FUNCTION(name) zap_status_t name ZIO_OPEN_ARGS
#define ZIO_CLOSE_FUNCTION(name) zap_status_t name ZIO_CLOSE_ARGS
#define ZIO_DESTROY_CHANNEL_FUNCTION(name) zap_status_t name ZIO_DESTROY_CHANNEL_ARGS
#define ZIO_CHANNEL_DESTROY_FUNCTION(name) zap_status_t name ZIO_CHANNEL_DESTROY_ARGS
#define ZIO_GET_ALARMS_FUNCTION(name) zap_status_t name ZIO_GET_ALARMS_ARGS
#define ZIO_COMMAND_FUNCTION(name) zap_status_t name ZIO_COMMAND_ARGS
#define ZIO_WAIT_FUNCTION(name) zap_status_t name ZIO_WAIT_ARGS
#define ZIO_READ_FUNCTION(name) zap_status_t name ZIO_READ_ARGS

View File

@ -9,9 +9,14 @@ static ZIO_SIGNAL_CB_FUNCTION(on_signal)
int main(int argc, char *argv[])
{
zap_span_t *span;
zap_global_set_default_logger(ZAP_LOG_LEVEL_DEBUG);
if (argc < 2) {
printf("umm no\n");
exit(-1);
}
if (zap_global_init() != ZAP_SUCCESS) {
fprintf(stderr, "Error loading OpenZAP\n");
exit(-1);
@ -19,7 +24,7 @@ int main(int argc, char *argv[])
printf("OpenZAP loaded\n");
if (zap_span_find(1, &span) != ZAP_SUCCESS) {
if (zap_span_find(atoi(argv[1]), &span) != ZAP_SUCCESS) {
fprintf(stderr, "Error finding OpenZAP span\n");
goto done;
}

View File

@ -605,7 +605,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
return NULL;
}
static zap_status_t process_event(zap_span_t *span, zap_event_t *event)
static __inline__ zap_status_t process_event(zap_span_t *span, zap_event_t *event)
{
zap_sigmsg_t sig;
zap_analog_data_t *data = event->channel->span->analog_data;
@ -708,7 +708,7 @@ static void *zap_analog_run(zap_thread_t *me, void *obj)
{
zap_event_t *event;
while (zap_span_next_event(span, &event) == ZAP_SUCCESS) {
if (event->e_type == ZAP_OOB_NOOP) {
if (event->enum_id == ZAP_OOB_NOOP) {
continue;
}
if (process_event(span, event) != ZAP_SUCCESS) {

View File

@ -211,7 +211,7 @@ static uint32_t hashfromstring(void *ky)
}
static zap_status_t zap_destroy_channel(zap_channel_t *zchan)
static zap_status_t zap_channel_destroy(zap_channel_t *zchan)
{
if (zap_test_flag(zchan, ZAP_CHANNEL_CONFIGURED)) {
@ -226,9 +226,9 @@ static zap_status_t zap_destroy_channel(zap_channel_t *zchan)
}
if (zchan->span->zio->destroy_channel) {
if (zchan->span->zio->channel_destroy) {
zap_log(ZAP_LOG_INFO, "Closing channel %u:%u fd:%d\n", zchan->span_id, zchan->chan_id, zchan->sockfd);
if (zchan->span->zio->destroy_channel(zchan) == ZAP_SUCCESS) {
if (zchan->span->zio->channel_destroy(zchan) == ZAP_SUCCESS) {
zap_clear_flag_locked(zchan, ZAP_CHANNEL_CONFIGURED);
} else {
zap_log(ZAP_LOG_ERROR, "Error Closing channel %u:%u fd:%d\n", zchan->span_id, zchan->chan_id, zchan->sockfd);
@ -239,6 +239,42 @@ static zap_status_t zap_destroy_channel(zap_channel_t *zchan)
return ZAP_SUCCESS;
}
zap_status_t zap_channel_get_alarms(zap_channel_t *zchan)
{
zap_status_t status = ZAP_FAIL;
if (zap_test_flag(zchan, ZAP_CHANNEL_CONFIGURED)) {
if (zchan->span->zio->get_alarms) {
if ((status = zchan->span->zio->get_alarms(zchan)) == ZAP_SUCCESS) {
*zchan->last_error = '\0';
if (zap_test_alarm_flag(zchan, ZAP_ALARM_RED)) {
snprintf(zchan->last_error + strlen(zchan->last_error), sizeof(zchan->last_error) - strlen(zchan->last_error), "RED/");
}
if (zap_test_alarm_flag(zchan, ZAP_ALARM_YELLOW)) {
snprintf(zchan->last_error + strlen(zchan->last_error), sizeof(zchan->last_error) - strlen(zchan->last_error), "YELLOW/");
}
if (zap_test_alarm_flag(zchan, ZAP_ALARM_BLUE)) {
snprintf(zchan->last_error + strlen(zchan->last_error), sizeof(zchan->last_error) - strlen(zchan->last_error), "BLUE/");
}
if (zap_test_alarm_flag(zchan, ZAP_ALARM_LOOPBACK)) {
snprintf(zchan->last_error + strlen(zchan->last_error), sizeof(zchan->last_error) - strlen(zchan->last_error), "LOOP/");
}
if (zap_test_alarm_flag(zchan, ZAP_ALARM_RECOVER)) {
snprintf(zchan->last_error + strlen(zchan->last_error), sizeof(zchan->last_error) - strlen(zchan->last_error), "RECOVER/");
}
*(zchan->last_error + strlen(zchan->last_error) - 1) = '\0';
}
} else {
status = ZAP_NOTIMPL;
}
}
return status;
}
zap_status_t zap_span_create(zap_io_interface_t *zio, zap_span_t **span)
{
zap_span_t *new_span = NULL;
@ -277,7 +313,7 @@ zap_status_t zap_span_close_all(void)
span = &globals.spans[i];
for(j = 0; j < span->chan_count; j++) {
zap_destroy_channel(&span->channels[i]);
zap_channel_destroy(&span->channels[i]);
}
if (span->mutex) {
@ -1903,7 +1939,7 @@ zap_status_t zap_global_destroy(void)
for(j = 1; j <= cur_span->chan_count; j++) {
zap_channel_t *cur_chan = &cur_span->channels[j];
if (zap_test_flag(cur_chan, ZAP_CHANNEL_CONFIGURED)) {
zap_destroy_channel(cur_chan);
zap_channel_destroy(cur_chan);
}
}
zap_mutex_unlock(cur_span->mutex);

View File

@ -46,13 +46,7 @@
static L2ULONG zap_time_now()
{
#ifdef WIN32
return timeGetTime();
#else
struct timeval tv;
gettimeofday(&tv, NULL);
return ((tv.tv_sec * 1000) + (tv.tv_usec / 1000));
#endif
return zap_current_time_in_ms();
}
static ZIO_CHANNEL_OUTGOING_CALL_FUNCTION(isdn_outgoing_call)
@ -173,9 +167,9 @@ static L3INT zap_isdn_931_34(void *pvt, L2UCHAR *msg, L2INT mlen)
static int zap_isdn_921_23(void *pvt, L2UCHAR *msg, L2INT mlen)
{
int ret;
//char bb[4096] = "";
//print_hex_bytes(msg+4, mlen-2, bb, sizeof(bb));
//zap_log(ZAP_LOG_DEBUG, "READ %d\n%s\n%s\n\n", (int)mlen-2, LINE, bb);
char bb[4096] = "";
print_hex_bytes(msg+4, mlen-2, bb, sizeof(bb));
zap_log(ZAP_LOG_DEBUG, "READ %d\n%s\n%s\n\n", (int)mlen-2, LINE, bb);
ret = Q931Rx23(pvt, msg, mlen);
if (ret != 0)
@ -395,6 +389,79 @@ static __inline__ void check_state(zap_span_t *span)
}
}
static __inline__ zap_status_t process_event(zap_span_t *span, zap_event_t *event)
{
zap_sigmsg_t sig;
zap_isdn_data_t *data = span->isdn_data;
memset(&sig, 0, sizeof(sig));
sig.chan_id = event->channel->chan_id;
sig.span_id = event->channel->span_id;
sig.channel = event->channel;
zap_log(ZAP_LOG_DEBUG, "EVENT [%s][%d:%d] STATE [%s]\n",
zap_oob_event2str(event->enum_id), event->channel->span_id, event->channel->chan_id, zap_channel_state2str(event->channel->state));
switch(event->enum_id) {
case ZAP_OOB_ALARM_TRAP:
{
sig.event_id = ZAP_OOB_ALARM_TRAP;
if (event->channel->state != ZAP_CHANNEL_STATE_DOWN) {
zap_set_state_locked(event->channel, ZAP_CHANNEL_STATE_TERMINATING);
}
zap_set_flag(event->channel, ZAP_CHANNEL_SUSPENDED);
zap_channel_get_alarms(event->channel);
data->sig_cb(&sig);
zap_log(ZAP_LOG_WARNING, "channel %d:%d (%d:%d) has alarms [%s]\n",
event->channel->span_id, event->channel->chan_id,
event->channel->physical_span_id, event->channel->physical_chan_id,
event->channel->last_error);
}
break;
case ZAP_OOB_ALARM_CLEAR:
{
sig.event_id = ZAP_OOB_ALARM_CLEAR;
zap_clear_flag(event->channel, ZAP_CHANNEL_SUSPENDED);
zap_channel_get_alarms(event->channel);
data->sig_cb(&sig);
}
break;
}
return ZAP_SUCCESS;
}
static __inline__ void check_events(zap_span_t *span)
{
zap_status_t status;
status = zap_span_poll_event(span, 5);
switch(status) {
case ZAP_SUCCESS:
{
zap_event_t *event;
while (zap_span_next_event(span, &event) == ZAP_SUCCESS) {
if (event->enum_id == ZAP_OOB_NOOP) {
continue;
}
if (process_event(span, event) != ZAP_SUCCESS) {
break;
}
}
}
break;
case ZAP_FAIL:
{
zap_log(ZAP_LOG_DEBUG, "Event Failure!\n");
}
break;
default:
break;
}
}
static void *zap_isdn_run(zap_thread_t *me, void *obj)
{
zap_span_t *span = (zap_span_t *) obj;
@ -417,7 +484,8 @@ static void *zap_isdn_run(zap_thread_t *me, void *obj)
Q921TimerTick(&data->q921);
check_state(span);
check_events(span);
switch(status) {
case ZAP_FAIL:
{

View File

@ -914,7 +914,7 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(wanpipe_next_event)
}
static ZIO_DESTROY_CHANNEL_FUNCTION(wanpipe_destroy_channel)
static ZIO_CHANNEL_DESTROY_FUNCTION(wanpipe_channel_destroy)
{
if (zchan->sockfd > -1) {
close(zchan->sockfd);
@ -947,7 +947,7 @@ zap_status_t wanpipe_init(zap_io_interface_t **zio)
wanpipe_interface.poll_event = wanpipe_poll_event;
#endif
wanpipe_interface.next_event = wanpipe_next_event;
wanpipe_interface.destroy_channel = wanpipe_destroy_channel;
wanpipe_interface.channel_destroy = wanpipe_channel_destroy;
*zio = &wanpipe_interface;
return ZAP_SUCCESS;

View File

@ -45,19 +45,14 @@ static struct {
} zt_globals;
#define ZT_INVALID_SOCKET -1
static const char ctlpath[] = "/dev/zap/ctl";
static zap_socket_t CONTROL_FD = ZT_INVALID_SOCKET;
static unsigned zt_open_range(zap_span_t *span, unsigned start, unsigned end, zap_chan_type_t type, char *name, char *number)
{
unsigned configured = 0, x;
const char ctlpath[] = "/dev/zap/ctl";
char path[] = "/dev/zap/channel";
zt_params_t ztp;
zap_socket_t ctlfd = ZT_INVALID_SOCKET;
if ((ctlfd = open(ctlpath, O_RDWR)) < 0) {
zap_log(ZAP_LOG_ERROR, "Cannot open control device\n");
return 0;
}
memset(&ztp, 0, sizeof(ztp));
@ -71,7 +66,7 @@ static unsigned zt_open_range(zap_span_t *span, unsigned start, unsigned end, za
if (sockfd != ZT_INVALID_SOCKET && zap_span_add_channel(span, sockfd, type, &zchan) == ZAP_SUCCESS) {
if (ioctl(sockfd, ZT_SPECIFY, &x)) {
zap_log(ZAP_LOG_ERROR, "failure configuring device %s chan %d fd %d (%s)\n", path, x, ctlfd, strerror(errno));
zap_log(ZAP_LOG_ERROR, "failure configuring device %s chan %d fd %d (%s)\n", path, x, sockfd, strerror(errno));
close(sockfd);
continue;
}
@ -132,9 +127,9 @@ static unsigned zt_open_range(zap_span_t *span, unsigned start, unsigned end, za
default:
break;
}
if (ioctl(ctlfd, ZT_CHANCONFIG, &cc)) {
if (ioctl(CONTROL_FD, ZT_CHANCONFIG, &cc)) {
zap_log(ZAP_LOG_ERROR, "failure configuring device %s chan %d fd %d (%s)\n",
path, x, ctlfd, strerror(errno));
path, x, CONTROL_FD, strerror(errno));
close(sockfd);
break;
}
@ -208,7 +203,7 @@ static unsigned zt_open_range(zap_span_t *span, unsigned start, unsigned end, za
}
}
close(ctlfd);
return configured;
}
@ -448,6 +443,25 @@ static ZIO_COMMAND_FUNCTION(zt_command)
return ZAP_SUCCESS;
}
static ZIO_GET_ALARMS_FUNCTION(zt_get_alarms)
{
struct zt_spaninfo info;
memset(&info, 0, sizeof(info));
info.span_no = zchan->physical_span_id;
if (ioctl(CONTROL_FD, ZT_SPANSTAT, &info)) {
snprintf(zchan->last_error, sizeof(zchan->last_error), "ioctl failed (%s)", strerror(errno));
snprintf(zchan->span->last_error, sizeof(zchan->span->last_error), "ioctl failed (%s)", strerror(errno));
return ZAP_FAIL;
}
zchan->alarm_flags = info.alarms;
return ZAP_SUCCESS;
}
static ZIO_WAIT_FUNCTION(zt_wait)
{
int32_t inflags = 0;
@ -478,10 +492,9 @@ static ZIO_WAIT_FUNCTION(zt_wait)
}
if (result > 0) {
*flags = pfds[0].revents;
inflags = pfds[0].revents;
}
*flags = ZAP_NO_FLAGS;
if (result < 0){
@ -595,6 +608,16 @@ ZIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event)
}
}
break;
case ZT_EVENT_ALARM:
{
event_id = ZAP_OOB_ALARM_TRAP;
}
break;
case ZT_EVENT_NOALARM:
{
event_id = ZAP_OOB_ALARM_CLEAR;
}
break;
default:
{
zap_log(ZAP_LOG_WARNING, "Unhandled event %d\n", zt_event_id);
@ -655,7 +678,7 @@ static ZIO_WRITE_FUNCTION(zt_write)
return ZAP_FAIL;
}
static ZIO_DESTROY_CHANNEL_FUNCTION(zt_destroy_channel)
static ZIO_CHANNEL_DESTROY_FUNCTION(zt_channel_destroy)
{
close(zchan->sockfd);
zchan->sockfd = ZT_INVALID_SOCKET;
@ -671,6 +694,11 @@ zap_status_t zt_init(zap_io_interface_t **zio)
memset(&zt_interface, 0, sizeof(zt_interface));
memset(&zt_globals, 0, sizeof(zt_globals));
if ((CONTROL_FD = open(ctlpath, O_RDWR)) < 0) {
zap_log(ZAP_LOG_ERROR, "Cannot open control device\n");
return 0;
}
zt_globals.codec_ms = 20;
zt_globals.wink_ms = 150;
zt_globals.flash_ms = 750;
@ -688,8 +716,8 @@ zap_status_t zt_init(zap_io_interface_t **zio)
zt_interface.write = zt_write;
zt_interface.poll_event = zt_poll_event;
zt_interface.next_event = zt_next_event;
zt_interface.destroy_channel = zt_destroy_channel;
zt_interface.channel_destroy = zt_channel_destroy;
zt_interface.get_alarms = zt_get_alarms;
*zio = &zt_interface;
return ZAP_SUCCESS;
@ -697,7 +725,7 @@ zap_status_t zt_init(zap_io_interface_t **zio)
zap_status_t zt_destroy(void)
{
close(CONTROL_FD);
memset(&zt_interface, 0, sizeof(zt_interface));
return ZAP_SUCCESS;
}