/*! \brief Helper function that creates an outgoing channel and returns it immediately */ static struct ast_channel *dial_transfer(const struct ast_channel *caller, const char *exten, const char *context) { char destination[AST_MAX_EXTENSION+AST_MAX_CONTEXT+1] = ""; struct ast_channel *chan = NULL; int cause; /* Fill the variable with the extension and context we want to call */ snprintf(destination, sizeof(destination), "%s@%s", exten, context); /* Now we request that chan_local prepare to call the destination */ if (!(chan = ast_request("Local", caller->nativeformats, caller, destination, &cause))) { return NULL; } /* Before we actually dial out let's inherit the appropriate dialplan variables */ ast_channel_inherit_variables(caller, chan); /* Since the above worked fine now we actually call it and return the channel */ if (ast_call(chan, destination, 0)) { ast_hangup(chan); return NULL; } return chan; }
static int app_control_dial(struct stasis_app_control *control, struct ast_channel *chan, void *data) { struct control_dial_args *args = data; int bridged; ast_channel_lock(chan); bridged = ast_channel_is_bridged(chan); ast_channel_unlock(chan); if (!bridged && add_to_dial_bridge(control, chan)) { return -1; } if (args->timeout && set_timeout(chan, args->timeout)) { return -1; } if (ast_call(chan, args->dialstring, 0)) { return -1; } ast_channel_publish_dial(NULL, chan, args->dialstring, NULL); return 0; }
/*! * \internal * \brief Helper function that creates an outgoing channel and returns it immediately. This function is nearly * identical to the dial_transfer function in bridge_basic.c, however it doesn't swap the * local channel and the channel that instigated the park. */ static struct ast_channel *park_local_transfer(struct ast_channel *parker, const char *context, const char *exten, struct transfer_channel_data *parked_channel_data) { char destination[AST_MAX_EXTENSION + AST_MAX_CONTEXT + 1]; struct ast_channel *parkee; struct ast_channel *parkee_side_2; int cause; /* Fill the variable with the extension and context we want to call */ snprintf(destination, sizeof(destination), "%s@%s", exten, context); /* Now we request that chan_local prepare to call the destination */ parkee = ast_request("Local", ast_channel_nativeformats(parker), NULL, parker, destination, &cause); if (!parkee) { return NULL; } /* Before we actually dial out let's inherit appropriate information. */ ast_channel_lock_both(parker, parkee); ast_channel_req_accountcodes(parkee, parker, AST_CHANNEL_REQUESTOR_REPLACEMENT); ast_connected_line_copy_from_caller(ast_channel_connected(parkee), ast_channel_caller(parker)); ast_channel_inherit_variables(parker, parkee); ast_channel_datastore_inherit(parker, parkee); ast_channel_unlock(parker); parkee_side_2 = ast_local_get_peer(parkee); ast_assert(parkee_side_2 != NULL); ast_channel_unlock(parkee); /* We need to have the parker subscribe to the new local channel before hand. */ if (create_parked_subscription_full(parker, ast_channel_uniqueid(parkee_side_2), 1, parked_channel_data)) { ast_channel_unref(parkee_side_2); ast_hangup(parkee); return NULL; } ast_bridge_set_transfer_variables(parkee_side_2, ast_channel_name(parker), 0); ast_channel_unref(parkee_side_2); /* Since the above worked fine now we actually call it and return the channel */ if (ast_call(parkee, destination, 0)) { ast_hangup(parkee); return NULL; } return parkee; }
static void *dialstring(void *string) { struct ast_channel *channel; char *bufptr,*destptr; int ms=10000; /* ms affects number of rings */ int cnt=0,first; char tech[256]; char tele[256]; char filename[256]; int answered=0; for(first=0, bufptr=(char *)string, destptr=tech; *bufptr&&cnt<256; cnt++){ if(*bufptr=='/' && !first) { *destptr=0; destptr=tele; first=1; } else if(*bufptr==',') { *destptr=0; destptr=filename; } else { *destptr=*bufptr; destptr++; } bufptr++; } *destptr=0; ast_log(LOG_DEBUG, "Printing string arg: %s Eos\n", (char *)string); if(strlen(tech)+strlen(tele)+strlen(filename) > 256) { ast_log(LOG_ERROR, "Autodial:Error string too long\n"); free(string); pthread_exit(NULL); } ast_log(LOG_DEBUG, "Autodial Tech %s(%d) Tele %s(%d) Filename %s(%d)\n",tech, (int)strlen(tech), tele, (int)strlen(tele), filename, (int)strlen(filename)); channel=ast_request(tech,AST_FORMAT_SLINEAR,tele); if(channel!=NULL){ ast_call(channel,tele,10000); } else { ast_log(LOG_ERROR, "Autodial:Sorry unable to obtain channel\n"); free(string); pthread_exit(NULL); } if(channel->_state==AST_STATE_UP) ast_log(LOG_DEBUG, "Autodial:Line is Up\n"); while(ms>0){ struct ast_frame *f; ms=ast_waitfor(channel,ms); f=ast_read(channel); if(!f){ ast_log(LOG_DEBUG, "Autodial:Hung Up\n"); break; } if (f->frametype==AST_FRAME_CONTROL) { if (f->subclass==AST_CONTROL_ANSWER) { ast_log(LOG_DEBUG, "Autodial:Phone Answered\n"); if (channel->_state==AST_STATE_UP) { char res; ast_streamfile(channel,filename,0); /* Press Five for snooze */ res=ast_waitstream(channel, "37"); if(res=='3'){ answered=1; set_snooze_alarm((char *)string,60); ast_streamfile(channel,"demo-thanks",0); ast_waitstream(channel, ""); } else if(res=='7'){ answered=1; ast_streamfile(channel,"demo-thanks",0); ast_waitstream(channel, ""); } ast_stopstream(channel); ms=0; } } else if (f->subclass==AST_CONTROL_RINGING) ast_log(LOG_DEBUG, "Autodial:Phone Ringing end\n"); } ast_frfree(f); } if(!answered) set_snooze_alarm((char *) string, 5); free(string); ast_hangup(channel); ast_log(LOG_DEBUG, "Autodial:Hung up channel\n"); pthread_exit(NULL); return NULL; }