#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <inttypes.h>
#include <pthread.h>
#include <errno.h>
#include <tiffio.h>
#include <spandsp.h>
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
Go to the source code of this file.
Defines | |
#define | MAX_BLOCK_SIZE 240 |
Functions | |
char * | description (void) |
Provides a description of the module. | |
char * | key (void) |
Returns the ASTERISK_GPL_KEY. | |
int | load_module (void) |
Initialize the module. | |
static void | phase_e_handler (t30_state_t *s, void *user_data, int result) |
static void | span_message (int level, const char *msg) |
static void | t30_flush (t30_state_t *s, int which) |
static int | txfax_exec (struct ast_channel *chan, void *data) |
int | unload_module (void) |
Cleanup all module structures, sockets, etc. | |
int | usecount (void) |
Provides a usecount. | |
Variables | |
static char * | app = "TxFAX" |
static char * | descrip |
LOCAL_USER_DECL | |
STANDARD_LOCAL_USER | |
static char * | synopsis = "Send a FAX file" |
static char * | tdesc = "Trivial FAX Transmit Application" |
#define MAX_BLOCK_SIZE 240 |
Definition at line 57 of file app_txfax.c.
char* description | ( | void | ) |
Provides a description of the module.
Definition at line 293 of file app_txfax.c.
00294 { 00295 return tdesc; 00296 }
char* key | ( | void | ) |
Returns the ASTERISK_GPL_KEY.
This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:
char *key(void) { return ASTERISK_GPL_KEY; }
Definition at line 308 of file app_txfax.c.
References ASTERISK_GPL_KEY.
00309 { 00310 return ASTERISK_GPL_KEY; 00311 }
int load_module | ( | void | ) |
Initialize the module.
Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.
Definition at line 287 of file app_txfax.c.
References ast_register_application(), and txfax_exec().
00288 { 00289 return ast_register_application(app, txfax_exec, synopsis, descrip); 00290 }
static void phase_e_handler | ( | t30_state_t * | s, | |
void * | user_data, | |||
int | result | |||
) | [static] |
Definition at line 79 of file app_txfax.c.
References ast_log(), LOG_DEBUG, and pbx_builtin_setvar_helper().
00080 { 00081 struct ast_channel *chan; 00082 char far_ident[21]; 00083 00084 chan = (struct ast_channel *) user_data; 00085 if (result == T30_ERR_OK) 00086 { 00087 t30_get_far_ident(s, far_ident); 00088 pbx_builtin_setvar_helper(chan, "REMOTESTATIONID", far_ident); 00089 } 00090 else 00091 { 00092 ast_log(LOG_DEBUG, "==============================================================================\n"); 00093 ast_log(LOG_DEBUG, "Fax send not successful - result (%d) %s.\n", result, t30_completion_code_to_str(result)); 00094 ast_log(LOG_DEBUG, "==============================================================================\n"); 00095 } 00096 }
static void span_message | ( | int | level, | |
const char * | msg | |||
) | [static] |
Definition at line 59 of file app_txfax.c.
References __LOG_DEBUG, __LOG_WARNING, and ast_log().
00060 { 00061 int ast_level; 00062 00063 if (level == SPAN_LOG_WARNING) 00064 ast_level = __LOG_WARNING; 00065 else if (level == SPAN_LOG_WARNING) 00066 ast_level = __LOG_WARNING; 00067 else 00068 ast_level = __LOG_DEBUG; 00069 ast_log(ast_level, __FILE__, __LINE__, __PRETTY_FUNCTION__, msg); 00070 }
static void t30_flush | ( | t30_state_t * | s, | |
int | which | |||
) | [static] |
static int txfax_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 99 of file app_txfax.c.
References ast_channel::_state, ast_answer(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_frfree(), AST_FRIENDLY_OFFSET, ast_log(), ast_read(), ast_set_read_format(), ast_set_write_format(), AST_STATE_UP, ast_waitfor(), ast_write(), ast_frame::data, FALSE, ast_frame::frametype, LOCAL_USER_ADD, LOCAL_USER_REMOVE, LOG_DEBUG, LOG_WARNING, MAX_BLOCK_SIZE, ast_channel::name, pbx_builtin_getvar_helper(), phase_e_handler(), ast_channel::readformat, s, ast_frame::samples, span_message(), t, TRUE, and ast_channel::writeformat.
Referenced by load_module().
00100 { 00101 int res = 0; 00102 char source_file[256]; 00103 char *x; 00104 char *s; 00105 char *t; 00106 char *v; 00107 int option; 00108 int len; 00109 t30_state_t fax; 00110 int calling_party; 00111 int verbose; 00112 int samples; 00113 00114 struct localuser *u; 00115 struct ast_frame *inf = NULL; 00116 struct ast_frame outf; 00117 00118 int original_read_fmt; 00119 int original_write_fmt; 00120 00121 uint8_t __buf[sizeof(uint16_t)*MAX_BLOCK_SIZE + 2*AST_FRIENDLY_OFFSET]; 00122 uint8_t *buf = __buf + AST_FRIENDLY_OFFSET; 00123 00124 if (chan == NULL) 00125 { 00126 ast_log(LOG_WARNING, "Fax transmit channel is NULL. Giving up.\n"); 00127 return -1; 00128 } 00129 00130 span_set_message_handler(span_message); 00131 00132 /* The next few lines of code parse out the filename and header from the input string */ 00133 if (data == NULL) 00134 { 00135 /* No data implies no filename or anything is present */ 00136 ast_log(LOG_WARNING, "Txfax requires an argument (filename)\n"); 00137 return -1; 00138 } 00139 00140 calling_party = FALSE; 00141 verbose = FALSE; 00142 source_file[0] = '\0'; 00143 00144 for (option = 0, v = s = data; v; option++, s++) 00145 { 00146 t = s; 00147 v = strchr(s, '|'); 00148 s = (v) ? v : s + strlen(s); 00149 strncpy((char *) buf, t, s - t); 00150 buf[s - t] = '\0'; 00151 if (option == 0) 00152 { 00153 /* The first option is always the file name */ 00154 len = s - t; 00155 if (len > 255) 00156 len = 255; 00157 strncpy(source_file, t, len); 00158 source_file[len] = '\0'; 00159 } 00160 else if (strncmp("caller", t, s - t) == 0) 00161 { 00162 calling_party = TRUE; 00163 } 00164 else if (strncmp("debug", t, s - t) == 0) 00165 { 00166 verbose = TRUE; 00167 } 00168 } 00169 00170 /* Done parsing */ 00171 00172 LOCAL_USER_ADD(u); 00173 00174 if (chan->_state != AST_STATE_UP) 00175 { 00176 /* Shouldn't need this, but checking to see if channel is already answered 00177 * Theoretically asterisk should already have answered before running the app */ 00178 res = ast_answer(chan); 00179 } 00180 00181 if (!res) 00182 { 00183 original_read_fmt = chan->readformat; 00184 if (original_read_fmt != AST_FORMAT_SLINEAR) 00185 { 00186 res = ast_set_read_format(chan, AST_FORMAT_SLINEAR); 00187 if (res < 0) 00188 { 00189 ast_log(LOG_WARNING, "Unable to set to linear read mode, giving up\n"); 00190 return -1; 00191 } 00192 } 00193 original_write_fmt = chan->writeformat; 00194 if (original_write_fmt != AST_FORMAT_SLINEAR) 00195 { 00196 res = ast_set_write_format(chan, AST_FORMAT_SLINEAR); 00197 if (res < 0) 00198 { 00199 ast_log(LOG_WARNING, "Unable to set to linear write mode, giving up\n"); 00200 res = ast_set_read_format(chan, original_read_fmt); 00201 if (res) 00202 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name); 00203 return -1; 00204 } 00205 } 00206 fax_init(&fax, calling_party, NULL); 00207 if (verbose) 00208 fax.logging.level = SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW; 00209 00210 x = pbx_builtin_getvar_helper(chan, "LOCALSTATIONID"); 00211 if (x && x[0]) 00212 t30_set_local_ident(&fax, x); 00213 x = pbx_builtin_getvar_helper(chan, "LOCALHEADERINFO"); 00214 if (x && x[0]) 00215 t30_set_header_info(&fax, x); 00216 t30_set_tx_file(&fax, source_file, -1, -1); 00217 //t30_set_phase_b_handler(&fax, phase_b_handler, chan); 00218 //t30_set_phase_d_handler(&fax, phase_d_handler, chan); 00219 t30_set_phase_e_handler(&fax, phase_e_handler, chan); 00220 while (ast_waitfor(chan, -1) > -1) 00221 { 00222 inf = ast_read(chan); 00223 if (inf == NULL) 00224 { 00225 res = -1; 00226 break; 00227 } 00228 if (inf->frametype == AST_FRAME_VOICE) 00229 { 00230 if (fax_rx(&fax, inf->data, inf->samples)) 00231 break; 00232 samples = (inf->samples <= MAX_BLOCK_SIZE) ? inf->samples : MAX_BLOCK_SIZE; 00233 len = fax_tx(&fax, (int16_t *) &buf[AST_FRIENDLY_OFFSET], samples); 00234 if (len) 00235 { 00236 memset(&outf, 0, sizeof(outf)); 00237 outf.frametype = AST_FRAME_VOICE; 00238 outf.subclass = AST_FORMAT_SLINEAR; 00239 outf.datalen = len*sizeof(int16_t); 00240 outf.samples = len; 00241 outf.data = &buf[AST_FRIENDLY_OFFSET]; 00242 outf.offset = AST_FRIENDLY_OFFSET; 00243 if (ast_write(chan, &outf) < 0) 00244 { 00245 ast_log(LOG_WARNING, "Unable to write frame to channel; %s\n", strerror(errno)); 00246 break; 00247 } 00248 } 00249 } 00250 ast_frfree(inf); 00251 } 00252 if (inf == NULL) 00253 { 00254 ast_log(LOG_DEBUG, "Got hangup\n"); 00255 res = -1; 00256 } 00257 if (original_read_fmt != AST_FORMAT_SLINEAR) 00258 { 00259 res = ast_set_read_format(chan, original_read_fmt); 00260 if (res) 00261 ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name); 00262 } 00263 if (original_write_fmt != AST_FORMAT_SLINEAR) 00264 { 00265 res = ast_set_write_format(chan, original_write_fmt); 00266 if (res) 00267 ast_log(LOG_WARNING, "Unable to restore write format on '%s'\n", chan->name); 00268 } 00269 fax_release(&fax); 00270 } 00271 else 00272 { 00273 ast_log(LOG_WARNING, "Could not answer channel '%s'\n", chan->name); 00274 } 00275 LOCAL_USER_REMOVE(u); 00276 return res; 00277 }
int unload_module | ( | void | ) |
Cleanup all module structures, sockets, etc.
This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).
Definition at line 280 of file app_txfax.c.
References ast_unregister_application(), and STANDARD_HANGUP_LOCALUSERS.
00281 { 00282 STANDARD_HANGUP_LOCALUSERS; 00283 return ast_unregister_application(app); 00284 }
int usecount | ( | void | ) |
Provides a usecount.
This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.
Definition at line 299 of file app_txfax.c.
References STANDARD_USECOUNT.
00300 { 00301 int res; 00302 00303 STANDARD_USECOUNT(res); 00304 return res; 00305 }
char* app = "TxFAX" [static] |
Definition at line 38 of file app_txfax.c.
char* descrip [static] |
Definition at line 42 of file app_txfax.c.
Definition at line 55 of file app_txfax.c.
Definition at line 53 of file app_txfax.c.
char* synopsis = "Send a FAX file" [static] |
Definition at line 40 of file app_txfax.c.
char* tdesc = "Trivial FAX Transmit Application" [static] |
Definition at line 36 of file app_txfax.c.