Chan.Answer(); Chan.StartMusic(); Chan.AutoService("start"); new_chan = OriginateSync("SIP/100012/100", "deadair", "s", "", ""); Chan.AutoService("stop"); results = Chan.Bridge(new_chan, ""); //new_chan.Hangup(); Chan.Wait(30000); Chan.Hangup(); Asterisk Ready. *CLI> dial s@chan2 [New Thread -1211528272 (LWP 1083)] *CLI> << Console call has been answered >> Channel OSS/dsp in autoservice mode Start[New Thread -1211794512 (LWP 1084)] Calling originate_helper synchronously... Calling ast_pbx_outgoing_exten [New Thread -1212060752 (LWP 1085)] Done ast_pbx_outgoing_exten Channel OSS/dsp in autoservice mode stopDeadair called from SIP/100012-f99f Dec 29 02:04:24 WARNING[1083]: channel.c:1316 ast_waitfor_nandfds: Thread -1211528272 Blocking 'SIP/100012-f99f', already blocked by thread -1212060752 in procedure ast_waitfor_nandfds *CLI> Detaching after fork from child process 1086. Dec 29 02:04:29 NOTICE[1079]: res_musiconhold.c:507 monmp3thread: Request to schedule in the past?!?! *CLI> show ch channel channels channeltypes *CLI> show channels Channel Location State Application(Data) SIP/100012-f99f s@deadair:1 Up Bridged Call(OSS/dsp) OSS/dsp s@chan2:1 Up JavaScript(testchan2.js) 2 active channels 2 active calls *CLI> Dec 29 02:04:45 WARNING[1084]: channel.c:1316 ast_waitfor_nandfds: Thread -1211794512 Blocking 'SIP/100012-f99f', already blocked by thread -1212060752 in procedure ast_waitfor_nandfds Detaching after fork from child process 1087. Dec 29 02:04:49 NOTICE[1079]: res_musiconhold.c:507 monmp3thread: Request to schedule in the past?!?! Dec 29 02:04:57 WARNING[1083]: chan_oss.c:854 oss_indicate: Don't know how to display condition 16 on OSS/dsp Dec 29 02:04:57 WARNING[1085]: channel.c:1316 ast_waitfor_nandfds: Thread -1212060752 Blocking 'SIP/100012-f99f', already blocked by thread -1212060752 in procedure ast_waitfor_nandfds Dec 29 02:04:58 NOTICE[1083]: app.c:78 ast_app_dtget: Huh....? no dial for indications? Dec 29 02:05:05 WARNING[1083]: chan_oss.c:854 oss_indicate: Don't know how to display condition 17 on OSS/dsp Detaching after fork from child process 1088. Dec 29 02:05:09 NOTICE[1079]: res_musiconhold.c:507 monmp3thread: Request to schedule in the past?!?! << Hangup on console >> [Thread -1212060752 (LWP 1085) exited] [Thread -1211528272 (zombie) exited] static JSBool chan_originatesync(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { struct fast_originate_helper *in; struct ast_channel *chan = NULL; char *channel = NULL, *exten = NULL, *context = NULL, *callerid = NULL, *tech = NULL,*data = NULL, *num = NULL, *timeout = NULL; int res = 0; int reason = 0; ast_verbose( "Calling originate_helper synchronously...\n"); *rval = BOOLEAN_TO_JSVAL( JS_FALSE ); if ( argc > 0 ) { channel = JS_GetStringBytes(JS_ValueToString(cx, argv[0])); context = JS_GetStringBytes(JS_ValueToString(cx, argv[1])); exten = JS_GetStringBytes(JS_ValueToString(cx, argv[2])); callerid = JS_GetStringBytes(JS_ValueToString(cx, argv[3])); timeout = JS_GetStringBytes(JS_ValueToString(cx, argv[4])); } else { ast_log(LOG_ERROR, "Error Origiante Sync called without enough arguments\n"); return JS_TRUE; // There was not enough arguments, but not a good enough reason to halt code execution } int timeout_int = atoi(timeout); if ( timeout_int == 0 ) timeout_int = 30000; tech = ast_strdupa(channel); if((data = strchr(tech,'/'))) { *data = '\0'; data++; } if(!(tech && data)) { ast_log(LOG_ERROR,"No channel technology or data\n"); return -1; } // OK allocate everything in = malloc(sizeof(struct fast_originate_helper)); if(!in) { ast_log(LOG_ERROR,"Origiante Sync: No Memory!\n"); return -1; } memset(in,0,sizeof(struct fast_originate_helper)); strncpy(in->tech,tech,sizeof(in->tech)); strncpy(in->data,data,sizeof(in->data)); in->timeout=timeout_int; //timeout; in->priority=1; // priority if(callerid) { if((num = strchr(callerid,':'))) { *num = '\0'; num++; strncpy(in->cid_num,num,sizeof(in->cid_num)); } strncpy(in->cid_name,callerid,sizeof(in->cid_name)); } strncpy(in->context,context,sizeof(in->context)); strncpy(in->exten,exten,sizeof(in->exten)); ast_verbose("Calling ast_pbx_outgoing_exten\n"); res = ast_pbx_outgoing_exten(in->tech, AST_FORMAT_SLINEAR, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1, NULL, NULL, NULL, &chan); ast_verbose("Done ast_pbx_outgoing_exten\n"); if ( chan ) { ast_mutex_unlock(&chan->lock); } /* Locked by ast_pbx_outgoing_exten or ast_pbx_outgoing_app */ if (!res) { // If this isn't here, SEG FAULT JSObject *obj_mine; struct jchan *jc2; char unique_obj[254] = ""; snprintf(unique_obj, sizeof(unique_obj), "NC%s", chan->uniqueid); jc2 = malloc(sizeof(struct jchan)); if ((obj_mine = JS_DefineObject(cx, obj, unique_obj, &chan_class, NULL, 0))) { memset(jc2, 0, sizeof(struct jchan)); jc2->chan = chan; jc2->flags = 0; JS_SetPrivate(cx, obj_mine, jc2); *rval = OBJECT_TO_JSVAL(obj_mine); return JS_TRUE; } //if ( jc2 ) // free(jc2); } ast_log(LOG_VERBOSE, "OriginateSync failed"); return JS_FALSE; } static JSBool bridge_helper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { struct ast_bridge_config config; struct jchan *jc2; struct jchan *jc = JS_GetPrivate(cx, obj); *rval = BOOLEAN_TO_JSVAL( JS_FALSE ); int bridge = 0; JSObject *myobj; ast_log(LOG_VERBOSE, "Bridge called..."); if(JSVAL_IS_OBJECT(argv[0])) { ast_log(LOG_VERBOSE, "We received an object"); //channel = JS_GetStringBytes(JS_ValueToString(cx, argv[0])); if ( JS_ValueToObject(cx, (jsval )argv[0], &myobj) ) { ast_log(LOG_VERBOSE, "Successfully received object in bridging"); jc2 = JS_GetPrivate(cx, myobj); } else { ast_log(LOG_VERBOSE, "Unsuccessfully received object in bridging"); return JS_FALSE; } } if ( jc2->chan == NULL) { ast_log(LOG_VERBOSE, "Bridge helper received invalid channel!"); return JS_FALSE; } //config = malloc(sizeof(struct ast_bridge_config)); memset(&config, 0, sizeof(struct ast_bridge_config)); ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT); ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT); config.timelimit = 0; config.play_warning = 0; config.warning_freq = 0; config.warning_sound=NULL; ast_mutex_unlock(&jc2->chan->lock); bridge = ast_bridge_call(jc->chan, jc2->chan, &config); // Now we hang up the peer channel if successful. // if ( bridge != AST_PBX_NO_HANGUP_PEER ) // Should we also check for AST_PBX_KEEP 0 ? // ast_hangup(jc2->chan); if ( bridge == 0 ) { ast_log(LOG_VERBOSE, "Successfully bridge channel %s with channel %s", jc->chan->name, jc2->chan->name); *rval = BOOLEAN_TO_JSVAL( JS_TRUE ); return JS_TRUE; // Everthing is OK now. } else { ast_log(LOG_VERBOSE, "Failed to bridge channel %s with channel %s", jc->chan->name, jc2->chan->name); } return JS_FALSE; } static JSBool autoservice_helper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { char *operand = NULL, *start = "START", *stop = "STOP"; int res = 0 ; struct jchan *jc = JS_GetPrivate(cx, obj); *rval = BOOLEAN_TO_JSVAL( JS_FALSE ); if ( argc > 0 && (operand = JS_GetStringBytes(JS_ValueToString(cx, argv[0])))) { if ( !strcasecmp(operand, start) ) { ast_verbose( "Channel %s in autoservice mode start\n", jc->chan->name); res = ast_autoservice_start(jc->chan); return JS_TRUE; } else if ( !strcasecmp(operand, stop) ) { ast_verbose ("Channel %s in autoservice mode stop\n", jc->chan->name); res = ast_autoservice_stop(jc->chan); return JS_TRUE; } else { return JS_FALSE; } if ( !res ) { *rval = BOOLEAN_TO_JSVAL( JS_TRUE); return JS_TRUE; } } ast_log(LOG_VERBOSE,"AutoService requires an argument Start or Stop\n"); return JS_FALSE; }