summaryrefslogtreecommitdiffstats
path: root/tinyDEMO/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'tinyDEMO/main.c')
-rw-r--r--tinyDEMO/main.c526
1 files changed, 526 insertions, 0 deletions
diff --git a/tinyDEMO/main.c b/tinyDEMO/main.c
new file mode 100644
index 0000000..913c8f1
--- /dev/null
+++ b/tinyDEMO/main.c
@@ -0,0 +1,526 @@
+/*
+* Copyright (C) 2009 Mamadou Diop.
+*
+* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
+*
+* This file is part of Open Source Doubango Framework.
+*
+* DOUBANGO is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DOUBANGO is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DOUBANGO.
+*
+*/
+#include "main.h"
+#include "common.h"
+
+#include "invite.h"
+#include "message.h"
+#include "options.h"
+#include "publish.h"
+#include "register.h"
+#include "subscribe.h"
+
+#include "tinydav.h" /* Doubango Audio/Video Framework */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#define LINE_DELIM "\n \r\n"
+
+/* === global variables === */
+ctx_t* ctx = tsk_null;
+
+const char* trim(const char*);
+int insert(char* dest, tsk_size_t index, tsk_size_t dest_size, char* src, tsk_size_t src_size);
+int update_param(const char* , const char* );
+int execute(const cmd_t* );
+
+/* === entry point === */
+int main(int argc, char** argv)
+{
+ char cmdbuf[4096];
+ tsk_buffer_t* buffer = tsk_null;
+ cmd_t* cmd = tsk_null;
+ tsk_bool_t comment = tsk_false;
+ int ret;
+ int i, index;
+ const char* start = tsk_null, *end = tsk_null;
+
+ int a = 32 | 1 | 2;
+
+ /* Copyright */
+ printf("Doubango Project (tinyDEMO)\nCopyright (C) 2009 - 2010 Mamadou Diop \n\n");
+
+ /* Initialize Network Layer ==> Mandatory */
+ tnet_startup();
+ /* Initialize Doubango Audio/Video Framework ==> will register all plugins(codecs and sessions)
+ * Not mandatory if you have your own plugins*/
+ tdav_init();
+
+ /* Print Usage */
+ //cmd_print_help();
+
+ /* create user's ctx */
+ if(!(ctx = ctx_create()) || !ctx->stack){
+ TSK_DEBUG_ERROR("Failed to create user's ctx.");
+ goto bail;
+ }
+
+ /* create new buffer */
+ if(!(buffer = tsk_buffer_create_null())){
+ TSK_DEBUG_ERROR("Failed to create new buffer.");
+ goto bail;
+ }
+
+ /* initial args */
+ for(i=1 /* index zero contains the exe path */, index=0; i<argc && argv[i]; i++){
+ if(index){
+ tsk_buffer_append(buffer, " ", 1);
+ }
+ tsk_buffer_append(buffer, argv[i], tsk_strlen(argv[i]));
+ }
+
+ /* If initial args ==> parse it now */
+ if(buffer->size){
+ TSK_DEBUG_INFO("Initial command-line: %s", buffer->data);
+ goto init_buffer;
+ }
+
+ /* always use fgets() instead of gets. gets() is considered to be unsafe.(Android and Mac OS X will warn) */
+ while(fgets(cmdbuf, sizeof(cmdbuf), stdin)){
+ TSK_DEBUG_INFO("Command-Line: %s", cmdbuf);
+ tsk_buffer_cleanup(buffer); /* cannot read from console while executing scenario */
+ tsk_buffer_append(buffer, cmdbuf, tsk_strlen(cmdbuf));
+init_buffer:
+ start = buffer->data;
+ //start = trim(start);
+ end = start + buffer->size;
+ if(start >= end){
+ TSK_DEBUG_INFO("Empty buffer");
+ continue;
+ }
+parse_buffer:
+ TSK_OBJECT_SAFE_FREE(cmd); /* Free old value */
+ cmd = cmd_parse(start, (end-start), &comment, ctx->params);
+ if(cmd){
+ if(comment || cmd->type == cmd_none){
+ goto nex_line;
+ }
+ }
+ else{
+ continue;
+ }
+
+ /* Load from scenario file? */
+ if(cmd->type == cmd_scenario){
+ FILE* file;
+ const opt_t* opt;
+ tsk_size_t read = 0;
+ tsk_bool_t rm_lf = tsk_false;
+ if((opt = opt_get_by_type(cmd->opts, opt_path)) && !tsk_strnullORempty(opt->value)){ /* --path option */
+ if((file = fopen(opt->value, "r"))){
+ memset(cmdbuf, '\0', sizeof(cmdbuf)), cmdbuf[0] = '\n';
+ read = fread(cmdbuf+1, sizeof(uint8_t), sizeof(cmdbuf)-1, file);
+ fclose(file), file = tsk_null;
+
+ if(read == 0){
+ TSK_DEBUG_ERROR("[%s] is empty.", opt->value);
+ goto nex_line;
+ }
+ else if(read == sizeof(cmdbuf)-1){
+ TSK_DEBUG_ERROR("Buffer too short.");
+
+ goto nex_line;
+ }
+ read++; /* \n */
+ /* repplace all '\' with spaces (easier than handling that in the ragel file) */
+ for(i=0; ((tsk_size_t)i)<read; i++){
+ if(cmdbuf[i] == '\\'){
+ cmdbuf[i] = ' ';
+ rm_lf = tsk_true;
+ }
+ else if(rm_lf && cmdbuf[i] == '\n'){
+ cmdbuf[i] = ' ';
+ rm_lf = tsk_false;
+ }
+ }
+ cmdbuf[read] = '\n';
+
+ /* insert embedded scenario */
+ if((index = tsk_strindexOf(start, (end-start), "\n")) == -1){ /* ++sn line */
+ index = buffer->size;
+ }
+ else{
+ index += (start - ((const char*)buffer->data));
+ }
+
+ if(tsk_buffer_insert(buffer, index, cmdbuf, read)){
+ continue;
+ }
+ else{
+ start = ((const char*)buffer->data) + index; // because insert use realloc()
+ end = (((const char*)buffer->data) + buffer->size);
+ goto nex_line;
+ }
+ }
+ else{
+ TSK_DEBUG_ERROR("Failed to open scenario-file [%s].", opt->value);
+ goto nex_line;
+ }
+ continue;
+ }
+ else{
+ TSK_DEBUG_ERROR("++scenario command must have --path option.");
+ continue;
+ }
+ }
+
+ /* execute current command */
+ switch(cmd->type){
+ case cmd_exit:
+ TSK_DEBUG_INFO("Exit/Quit");
+ goto bail;
+ default:
+ ret = execute(cmd);
+ break;
+ }
+
+ /* next line */
+nex_line:
+ if((index = tsk_strindexOf(start, (end - start), "\n")) !=-1){
+ start += index;
+ while((start < end) && isspace(*start)){
+ start ++;
+ }
+ if((start + 2/*++*/) < end){
+ goto parse_buffer; /* next line */
+ }
+ else{
+ continue; /* wait for new commands */
+ }
+ }
+ } /* while(buffer) */
+
+
+bail:
+
+ /* Free current command */
+ TSK_OBJECT_SAFE_FREE(cmd);
+ /* Free buffer */
+ TSK_OBJECT_SAFE_FREE(buffer);
+ /* Destroy the user's ctx */
+ TSK_OBJECT_SAFE_FREE(ctx);
+ /* Deinitialize Doubango Audio/Video Framework ==> will unregister all plugins(codecs and sessions)
+ * Not mandatory */
+ tdav_init();
+ /* Uninitilize Network Layer */
+ tnet_cleanup();
+
+#if ANDROID
+ exit(0);
+#endif
+ return 0;
+}
+
+const char* trim(const char* str)
+{
+ while(isspace(*str)){
+ str++;
+ }
+ return str;
+}
+
+int update_param(const char* pname, const char* pvalue)
+{
+ if(ctx->params && pname){
+ const tsk_param_t* param;
+ if((param = tsk_params_get_param_by_name(ctx->params, pname))){
+ tsk_strupdate(&TSK_PARAM(param)->value, pvalue);
+ return 0;
+ }
+ else{
+ TSK_DEBUG_INFO("[%s] parameter does not exist", pname);
+ }
+ }
+ else{
+ TSK_DEBUG_ERROR("Invalid parameter");
+ }
+ return -1;
+}
+
+int execute(const cmd_t* cmd)
+{
+ int ret = 0;
+ tsip_ssession_id_t sid;
+ tsk_istr_t istr;
+
+ if(!cmd){
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ tsk_safeobj_lock(ctx);
+
+ switch(cmd->type){
+ case cmd_audio:
+ case cmd_audiovideo:
+ {
+ TSK_DEBUG_INFO("command=audio/video");
+ if((sid = invite_handle_cmd(cmd->type, cmd->opts)) != TSIP_SSESSION_INVALID_ID){
+ if(cmd->sidparam){
+ tsk_itoa(sid, &istr);
+ update_param(cmd->sidparam, istr);
+ }
+ }
+ break;
+ }
+ case cmd_config_session:
+ {
+ TSK_DEBUG_INFO("command=config-session");
+ break;
+ }
+ case cmd_config_stack:
+ {
+ TSK_DEBUG_INFO("command=config-satck");
+ ret = stack_config(cmd->opts);
+ break;
+ }
+ case cmd_dtmf:
+ {
+ const opt_t* opt;
+ TSK_DEBUG_INFO("command=dtmf");
+ if(!(opt = opt_get_by_type(cmd->opts, opt_sid)) || tsk_strnullORempty(opt->value)){ /* --sid option */
+ TSK_DEBUG_ERROR("++dtmf command need --sid option");
+ break;
+ }
+ if(!(opt = opt_get_by_type(cmd->opts, opt_event)) || tsk_strnullORempty(opt->value)){ /* --event option */
+ TSK_DEBUG_ERROR("++dtmf command need --event option");
+ break;
+ }
+ invite_handle_cmd(cmd->type, cmd->opts);
+ break;
+ }
+ case cmd_dump:
+ {
+ TSK_DEBUG_INFO("command=dump");
+ ret = stack_dump();
+ break;
+ }
+ case cmd_ect:
+ {
+ const opt_t* opt;
+ TSK_DEBUG_INFO("command=ect");
+ if((opt = opt_get_by_type(cmd->opts, opt_sid)) && !tsk_strnullORempty(opt->value)){
+ TSK_DEBUG_ERROR("++ect command need --sid option");
+ ret = -1;
+ break;
+ }
+ if((opt = opt_get_by_type(cmd->opts, opt_to)) && !tsk_strnullORempty(opt->value)){
+ TSK_DEBUG_ERROR("++ect command need --to option");
+ ret = -1;
+ break;
+ }
+ invite_handle_cmd(cmd->type, cmd->opts);
+ break;
+ }
+ case cmd_exit:
+ {
+ TSK_DEBUG_INFO("command=exit");
+ goto bail;
+ break;
+ }
+ case cmd_file:
+ {
+ const opt_t* opt;
+ TSK_DEBUG_INFO("command=file");
+ if(!(opt = opt_get_by_type(cmd->opts, opt_path)) || tsk_strnullORempty(opt->value)){
+ TSK_DEBUG_ERROR("++file command need --path option");
+ break;
+ }
+ if((sid = invite_handle_cmd(cmd->type, cmd->opts)) != TSIP_SSESSION_INVALID_ID){
+ if(cmd->sidparam){
+ tsk_itoa(sid, &istr);
+ update_param(cmd->sidparam, istr);
+ }
+ }
+ break;
+ }
+ case cmd_hangup:
+ {
+ const opt_t* opt;
+ TSK_DEBUG_INFO("command=hangup");
+ if((opt = opt_get_by_type(cmd->opts, opt_sid)) && !tsk_strnullORempty(opt->value)){ /* --sid option */
+ ret = session_hangup(tsk_atoll(opt->value));
+ }
+ else{
+ TSK_DEBUG_ERROR("++hangup command need --sid option");
+ ret = -1;
+ }
+ break;
+ }
+ case cmd_help:
+ {
+ TSK_DEBUG_INFO("command=help");
+ cmd_print_help();
+ break;
+ }
+ case cmd_hold:
+ {
+ const opt_t* opt;
+ TSK_DEBUG_INFO("command=hold");
+ if((opt = opt_get_by_type(cmd->opts, opt_sid)) && !tsk_strnullORempty(opt->value)){ /* --sid option */
+ invite_handle_cmd(cmd->type, cmd->opts);
+ }
+ else{
+ TSK_DEBUG_ERROR("++hold command need --sid option");
+ ret = -1;
+ }
+ break;
+ }
+ case cmd_message:
+ {
+ TSK_DEBUG_INFO("command=message");
+ if((sid = message_handle_cmd(cmd->type, cmd->opts)) != TSIP_SSESSION_INVALID_ID){
+ if(cmd->sidparam){
+ tsk_itoa(sid, &istr);
+ update_param(cmd->sidparam, istr);
+ }
+ }
+ break;
+ }
+
+ case cmd_options:
+ {
+ TSK_DEBUG_INFO("command=options");
+ if((sid = options_handle_cmd(cmd->type, cmd->opts)) != TSIP_SSESSION_INVALID_ID){
+ if(cmd->sidparam){
+ tsk_itoa(sid, &istr);
+ update_param(cmd->sidparam, istr);
+ }
+ }
+ break;
+ }
+ case cmd_publish:
+ {
+ TSK_DEBUG_INFO("command=publish");
+ if((sid = publish_handle_cmd(cmd->type, cmd->opts)) != TSIP_SSESSION_INVALID_ID){
+ if(cmd->sidparam){
+ tsk_itoa(sid, &istr);
+ update_param(cmd->sidparam, istr);
+ }
+ }
+ break;
+ }
+ case cmd_register:
+ {
+ TSK_DEBUG_INFO("command=register");
+ if((sid = register_handle_cmd(cmd->type, cmd->opts)) != TSIP_SSESSION_INVALID_ID){
+ if(cmd->sidparam){
+ tsk_itoa(sid, &istr);
+ update_param(cmd->sidparam, istr);
+ }
+ }
+ break;
+ }
+ case cmd_resume:
+ {
+ const opt_t* opt;
+ TSK_DEBUG_INFO("command=resume");
+ if((opt = opt_get_by_type(cmd->opts, opt_sid)) && !tsk_strnullORempty(opt->value)){ /* --sid option */
+ invite_handle_cmd(cmd->type, cmd->opts);
+ }
+ else{
+ TSK_DEBUG_ERROR("++resume command need --sid option");
+ ret = -1;
+ }
+ break;
+ }
+ case cmd_run:
+ {
+ TSK_DEBUG_INFO("command=run");
+ ret = stack_run(cmd->opts);
+ break;
+ }
+ case cmd_scenario:
+ {
+ TSK_DEBUG_INFO("command=scenario");
+ break;
+ }
+ case cmd_sleep:
+ {
+ const opt_t* opt;
+ double seconds;
+
+ tsk_safeobj_unlock(ctx); /* beacuse of callback function */
+
+ if((opt = opt_get_by_type(cmd->opts, opt_sec)) && !tsk_strnullORempty(opt->value)){ /* --sec option */
+ seconds = strtod(opt->value, tsk_null); /* strtod() is better than atof() */
+ if(seconds<=0){
+ printf("\n==== Press ENTER to continue...\n");
+ getchar();
+ }
+ else{
+ TSK_DEBUG_INFO("Sleeping %f seconds", seconds);
+ tsk_thread_sleep((uint64_t)(seconds * 1000));
+ }
+ }
+ else{
+ TSK_DEBUG_WARN("++sleep need --sec option.");
+ }
+ return 0; /* bail: will unlock again */
+ }
+ case cmd_sms:
+ {
+ TSK_DEBUG_INFO("command=sms");
+ if((sid = message_handle_cmd(cmd->type, cmd->opts)) != TSIP_SSESSION_INVALID_ID){
+ if(cmd->sidparam){
+ tsk_itoa(sid, &istr);
+ update_param(cmd->sidparam, istr);
+ }
+ }
+ break;
+ }
+ case cmd_stop:
+ {
+ TSK_DEBUG_INFO("command=stop");
+ tsip_stack_stop(ctx->stack);
+ break;
+ }
+ case cmd_subscribe:
+ {
+ TSK_DEBUG_INFO("command=subscribe");
+ if((sid = subscribe_handle_cmd(cmd->type, cmd->opts)) != TSIP_SSESSION_INVALID_ID){
+ if(cmd->sidparam){
+ tsk_itoa(sid, &istr);
+ update_param(cmd->sidparam, istr);
+ }
+ }
+ break;
+ }
+ case cmd_video:
+ {
+ TSK_DEBUG_INFO("command=video");
+ break;
+ }
+ default:
+ {
+ TSK_DEBUG_ERROR("%d not a valid command.", cmd);
+ break;
+ }
+ }
+
+bail:
+ tsk_safeobj_unlock(ctx);
+
+ return ret;
+}
OpenPOWER on IntegriCloud