#include "asterisk.h"
#include <signal.h>
#include "asterisk/pbx.h"
#include "asterisk/causes.h"
#include "asterisk/musiconhold.h"
#include "asterisk/transcap.h"
#include "sig_ss7.h"
Go to the source code of this file.
Defines | |
#define | SIG_SS7_DEADLOCK_AVOIDANCE(p) |
Functions | |
static unsigned char | cid_pres2ss7pres (int cid_pres) |
static unsigned char | cid_pres2ss7screen (int cid_pres) |
int | sig_ss7_add_sigchan (struct sig_ss7_linkset *linkset, int which, int ss7type, int transport, int inalarm, int networkindicator, int pointcode, int adjpointcode) |
Setup and add a SS7 link channel. | |
int | sig_ss7_answer (struct sig_ss7_chan *p, struct ast_channel *ast) |
SS7 answer channel. | |
int | sig_ss7_available (struct sig_ss7_chan *p) |
Determine if the specified channel is available for an outgoing call. | |
int | sig_ss7_call (struct sig_ss7_chan *p, struct ast_channel *ast, char *rdest) |
Dial out using the specified SS7 channel. | |
void | sig_ss7_chan_delete (struct sig_ss7_chan *doomed) |
Delete the sig_ss7 private channel structure. | |
sig_ss7_chan * | sig_ss7_chan_new (void *pvt_data, struct sig_ss7_callback *callback, struct sig_ss7_linkset *ss7) |
Create a new sig_ss7 private channel structure. | |
void | sig_ss7_fixup (struct ast_channel *oldchan, struct ast_channel *newchan, struct sig_ss7_chan *pchan) |
Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links. | |
static void | sig_ss7_handle_link_exception (struct sig_ss7_linkset *linkset, int which) |
int | sig_ss7_hangup (struct sig_ss7_chan *p, struct ast_channel *ast) |
SS7 hangup channel. | |
int | sig_ss7_indicate (struct sig_ss7_chan *p, struct ast_channel *chan, int condition, const void *data, size_t datalen) |
SS7 answer channel. | |
void | sig_ss7_init_linkset (struct sig_ss7_linkset *ss7) |
Initialize the SS7 linkset control. | |
void | sig_ss7_link_alarm (struct sig_ss7_linkset *linkset, int which) |
Notify the SS7 layer that the link is in alarm. | |
void | sig_ss7_link_noalarm (struct sig_ss7_linkset *linkset, int which) |
Notify the SS7 layer that the link is no longer in alarm. | |
static void | sig_ss7_lock_owner (struct sig_ss7_linkset *ss7, int chanpos) |
static void | sig_ss7_lock_private (struct sig_ss7_chan *p) |
static void | sig_ss7_loopback (struct sig_ss7_chan *p, int enable) |
static struct ast_channel * | sig_ss7_new_ast_channel (struct sig_ss7_chan *p, int state, int ulaw, int transfercapability, char *exten, const struct ast_channel *requestor) |
static int | sig_ss7_play_tone (struct sig_ss7_chan *p, enum sig_ss7_tone tone) |
static void | sig_ss7_queue_control (struct sig_ss7_linkset *ss7, int chanpos, int subclass) |
static void | sig_ss7_queue_frame (struct sig_ss7_linkset *ss7, int chanpos, struct ast_frame *frame) |
ast_channel * | sig_ss7_request (struct sig_ss7_chan *p, enum sig_ss7_law law, const struct ast_channel *requestor, int transfercapability) |
SS7 channel request. | |
void | sig_ss7_set_alarm (struct sig_ss7_chan *p, int in_alarm) |
static void | sig_ss7_set_caller_id (struct sig_ss7_chan *p) |
static void | sig_ss7_set_dialing (struct sig_ss7_chan *p, int is_dialing) |
static void | sig_ss7_set_digital (struct sig_ss7_chan *p, int is_digital) |
static void | sig_ss7_set_dnid (struct sig_ss7_chan *p, const char *dnid) |
static int | sig_ss7_set_echocanceller (struct sig_ss7_chan *p, int enable) |
static void | sig_ss7_set_inservice (struct sig_ss7_chan *p, int is_inservice) |
static void | sig_ss7_set_locallyblocked (struct sig_ss7_chan *p, int is_blocked) |
static void | sig_ss7_set_remotelyblocked (struct sig_ss7_chan *p, int is_blocked) |
static void | sig_ss7_unlock_private (struct sig_ss7_chan *p) |
static void | ss7_apply_plan_to_number (char *buf, size_t size, const struct sig_ss7_linkset *ss7, const char *number, const unsigned nai) |
static void | ss7_block_cics (struct sig_ss7_linkset *linkset, int startcic, int endcic, unsigned int dpc, unsigned char state[], int block) |
static int | ss7_find_cic (struct sig_ss7_linkset *linkset, int cic, unsigned int dpc) |
static int | ss7_grab (struct sig_ss7_chan *pvt, struct sig_ss7_linkset *ss7) |
static void | ss7_handle_cqm (struct sig_ss7_linkset *linkset, int startcic, int endcic, unsigned int dpc) |
static void | ss7_hangup_cics (struct sig_ss7_linkset *linkset, int startcic, int endcic, unsigned int dpc) |
static void | ss7_inservice (struct sig_ss7_linkset *linkset, int startcic, int endcic, unsigned int dpc) |
void * | ss7_linkset (void *data) |
static int | ss7_pres_scr2cid_pres (char presentation_ind, char screening_ind) |
static void | ss7_rel (struct sig_ss7_linkset *ss7) |
static void | ss7_reset_linkset (struct sig_ss7_linkset *linkset) |
static void | ss7_start_call (struct sig_ss7_chan *p, struct sig_ss7_linkset *linkset) |
Richard Mudgett <rmudgett@digium.com>
Definition in file sig_ss7.c.
#define SIG_SS7_DEADLOCK_AVOIDANCE | ( | p | ) |
Value:
do { \ sig_ss7_unlock_private(p); \ usleep(1); \ sig_ss7_lock_private(p); \ } while (0)
Definition at line 46 of file sig_ss7.c.
Referenced by ss7_grab().
static unsigned char cid_pres2ss7pres | ( | int | cid_pres | ) | [static] |
static unsigned char cid_pres2ss7screen | ( | int | cid_pres | ) | [static] |
int sig_ss7_add_sigchan | ( | struct sig_ss7_linkset * | linkset, | |
int | which, | |||
int | ss7type, | |||
int | transport, | |||
int | inalarm, | |||
int | networkindicator, | |||
int | pointcode, | |||
int | adjpointcode | |||
) |
Setup and add a SS7 link channel.
linkset | Controlling linkset for the channel. | |
which | Link index of the signaling channel. | |
ss7type | Switch type of the linkset | |
transport | Signaling transport of channel. | |
inalarm | Non-zero if the channel is in alarm. | |
networkindicator | User configuration parameter. | |
pointcode | User configuration parameter. | |
adjpointcode | User configuration parameter. |
0 | on success. | |
-1 | on error. |
Definition at line 1158 of file sig_ss7.c.
References ast_log(), sig_ss7_linkset::fds, sig_ss7_linkset::linkstate, LINKSTATE_DOWN, LINKSTATE_INALARM, LOG_ERROR, LOG_WARNING, sig_ss7_linkset::ss7, and sig_ss7_linkset::type.
Referenced by linkset_addsigchan().
01159 { 01160 if (!linkset->ss7) { 01161 linkset->type = ss7type; 01162 linkset->ss7 = ss7_new(ss7type); 01163 if (!linkset->ss7) { 01164 ast_log(LOG_ERROR, "Can't create new SS7!\n"); 01165 return -1; 01166 } 01167 } 01168 01169 ss7_set_network_ind(linkset->ss7, networkindicator); 01170 ss7_set_pc(linkset->ss7, pointcode); 01171 01172 if (ss7_add_link(linkset->ss7, transport, linkset->fds[which])) { 01173 ast_log(LOG_WARNING, "Could not add SS7 link!\n"); 01174 } 01175 01176 if (inalarm) { 01177 linkset->linkstate[which] = LINKSTATE_DOWN | LINKSTATE_INALARM; 01178 ss7_link_alarm(linkset->ss7, linkset->fds[which]); 01179 } else { 01180 linkset->linkstate[which] = LINKSTATE_DOWN; 01181 ss7_link_noalarm(linkset->ss7, linkset->fds[which]); 01182 } 01183 01184 ss7_set_adjpc(linkset->ss7, linkset->fds[which], adjpointcode); 01185 01186 return 0; 01187 }
int sig_ss7_answer | ( | struct sig_ss7_chan * | p, | |
struct ast_channel * | ast | |||
) |
SS7 answer channel.
p | Signaling private structure pointer. | |
ast | Asterisk channel structure pointer. |
0 | on success. | |
-1 | on error. |
Definition at line 1433 of file sig_ss7.c.
References ast_log(), LOG_WARNING, sig_ss7_chan::proceeding, sig_ss7_linkset::span, sig_ss7_chan::ss7, sig_ss7_linkset::ss7, ss7_grab(), ss7_rel(), and sig_ss7_chan::ss7call.
Referenced by dahdi_answer().
01434 { 01435 int res; 01436 01437 if (!ss7_grab(p, p->ss7)) { 01438 p->proceeding = 1; 01439 res = isup_anm(p->ss7->ss7, p->ss7call); 01440 ss7_rel(p->ss7); 01441 } else { 01442 ast_log(LOG_WARNING, "Unable to grab SS7 on span %d\n", p->ss7->span); 01443 res = -1; 01444 } 01445 return res; 01446 }
int sig_ss7_available | ( | struct sig_ss7_chan * | p | ) |
Determine if the specified channel is available for an outgoing call.
p | Signaling private structure pointer. |
TRUE | if the channel is available. |
Definition at line 1197 of file sig_ss7.c.
References sig_ss7_chan::inalarm, sig_ss7_chan::locallyblocked, sig_ss7_chan::owner, sig_ss7_chan::remotelyblocked, sig_ss7_chan::ss7, and sig_ss7_chan::ss7call.
Referenced by available().
01198 { 01199 if (!p->ss7) { 01200 /* Something is wrong here. A SS7 channel without the ss7 pointer? */ 01201 return 0; 01202 } 01203 01204 if (!p->inalarm && !p->owner && !p->ss7call 01205 && !p->locallyblocked && !p->remotelyblocked) { 01206 return 1; 01207 } 01208 01209 return 0; 01210 }
int sig_ss7_call | ( | struct sig_ss7_chan * | p, | |
struct ast_channel * | ast, | |||
char * | rdest | |||
) |
Dial out using the specified SS7 channel.
p | Signaling private structure pointer. | |
ast | Asterisk channel structure pointer. | |
rdest | Dialstring. |
0 | on success. | |
-1 | on error. |
Definition at line 1233 of file sig_ss7.c.
References ast_party_connected_line::ani2, ast_copy_string(), ast_log(), ast_setstate(), AST_STATE_DIALING, sig_ss7_linkset::called_nai, sig_ss7_linkset::calling_nai, sig_ss7_chan::cic, cid_pres2ss7pres(), cid_pres2ss7screen(), ast_channel::connected, sig_ss7_chan::dpc, sig_ss7_chan::gen_add_nai, sig_ss7_chan::gen_add_num_plan, sig_ss7_chan::gen_add_pres_ind, sig_ss7_chan::gen_add_type, sig_ss7_chan::hidecallerid, ast_party_connected_line::id, sig_ss7_linkset::internationalprefix, LOG_ERROR, LOG_WARNING, sig_ss7_linkset::nationalprefix, ast_party_id::number, pbx_builtin_getvar_helper(), ast_party_number::presentation, sig_ss7_set_dialing(), sig_ss7_chan::ss7, sig_ss7_linkset::ss7, ss7_grab(), SS7_NAI_DYNAMIC, ss7_rel(), sig_ss7_chan::ss7call, ast_party_number::str, sig_ss7_chan::stripmsd, sig_ss7_chan::use_callingpres, and ast_party_number::valid.
Referenced by dahdi_call().
01234 { 01235 char ss7_called_nai; 01236 int called_nai_strip; 01237 char ss7_calling_nai; 01238 int calling_nai_strip; 01239 const char *charge_str = NULL; 01240 const char *gen_address = NULL; 01241 const char *gen_digits = NULL; 01242 const char *gen_dig_type = NULL; 01243 const char *gen_dig_scheme = NULL; 01244 const char *gen_name = NULL; 01245 const char *jip_digits = NULL; 01246 const char *lspi_ident = NULL; 01247 const char *rlt_flag = NULL; 01248 const char *call_ref_id = NULL; 01249 const char *call_ref_pc = NULL; 01250 const char *send_far = NULL; 01251 char *c; 01252 char *l; 01253 char dest[256]; 01254 01255 ast_copy_string(dest, rdest, sizeof(dest)); 01256 01257 c = strchr(dest, '/'); 01258 if (c) { 01259 c++; 01260 } else { 01261 c = ""; 01262 } 01263 if (strlen(c) < p->stripmsd) { 01264 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd); 01265 return -1; 01266 } 01267 01268 if (!p->hidecallerid) { 01269 l = ast->connected.id.number.valid ? ast->connected.id.number.str : NULL; 01270 } else { 01271 l = NULL; 01272 } 01273 01274 if (ss7_grab(p, p->ss7)) { 01275 ast_log(LOG_WARNING, "Failed to grab SS7!\n"); 01276 return -1; 01277 } 01278 01279 p->ss7call = isup_new_call(p->ss7->ss7); 01280 if (!p->ss7call) { 01281 ss7_rel(p->ss7); 01282 ast_log(LOG_ERROR, "Unable to allocate new SS7 call!\n"); 01283 return -1; 01284 } 01285 01286 called_nai_strip = 0; 01287 ss7_called_nai = p->ss7->called_nai; 01288 if (ss7_called_nai == SS7_NAI_DYNAMIC) { /* compute dynamically */ 01289 if (strncmp(c + p->stripmsd, p->ss7->internationalprefix, strlen(p->ss7->internationalprefix)) == 0) { 01290 called_nai_strip = strlen(p->ss7->internationalprefix); 01291 ss7_called_nai = SS7_NAI_INTERNATIONAL; 01292 } else if (strncmp(c + p->stripmsd, p->ss7->nationalprefix, strlen(p->ss7->nationalprefix)) == 0) { 01293 called_nai_strip = strlen(p->ss7->nationalprefix); 01294 ss7_called_nai = SS7_NAI_NATIONAL; 01295 } else { 01296 ss7_called_nai = SS7_NAI_SUBSCRIBER; 01297 } 01298 } 01299 isup_set_called(p->ss7call, c + p->stripmsd + called_nai_strip, ss7_called_nai, p->ss7->ss7); 01300 01301 calling_nai_strip = 0; 01302 ss7_calling_nai = p->ss7->calling_nai; 01303 if ((l != NULL) && (ss7_calling_nai == SS7_NAI_DYNAMIC)) { /* compute dynamically */ 01304 if (strncmp(l, p->ss7->internationalprefix, strlen(p->ss7->internationalprefix)) == 0) { 01305 calling_nai_strip = strlen(p->ss7->internationalprefix); 01306 ss7_calling_nai = SS7_NAI_INTERNATIONAL; 01307 } else if (strncmp(l, p->ss7->nationalprefix, strlen(p->ss7->nationalprefix)) == 0) { 01308 calling_nai_strip = strlen(p->ss7->nationalprefix); 01309 ss7_calling_nai = SS7_NAI_NATIONAL; 01310 } else { 01311 ss7_calling_nai = SS7_NAI_SUBSCRIBER; 01312 } 01313 } 01314 isup_set_calling(p->ss7call, l ? (l + calling_nai_strip) : NULL, ss7_calling_nai, 01315 p->use_callingpres ? cid_pres2ss7pres(ast->connected.id.number.presentation) : (l ? SS7_PRESENTATION_ALLOWED : SS7_PRESENTATION_RESTRICTED), 01316 p->use_callingpres ? cid_pres2ss7screen(ast->connected.id.number.presentation) : SS7_SCREENING_USER_PROVIDED); 01317 01318 isup_set_oli(p->ss7call, ast->connected.ani2); 01319 isup_init_call(p->ss7->ss7, p->ss7call, p->cic, p->dpc); 01320 01321 /* Set the charge number if it is set */ 01322 charge_str = pbx_builtin_getvar_helper(ast, "SS7_CHARGE_NUMBER"); 01323 if (charge_str) 01324 isup_set_charge(p->ss7call, charge_str, SS7_ANI_CALLING_PARTY_SUB_NUMBER, 0x10); 01325 01326 gen_address = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_ADDRESS"); 01327 if (gen_address) 01328 isup_set_gen_address(p->ss7call, gen_address, p->gen_add_nai,p->gen_add_pres_ind, p->gen_add_num_plan,p->gen_add_type); /* need to add some types here for NAI,PRES,TYPE */ 01329 01330 gen_digits = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGITS"); 01331 gen_dig_type = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGTYPE"); 01332 gen_dig_scheme = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_DIGSCHEME"); 01333 if (gen_digits) 01334 isup_set_gen_digits(p->ss7call, gen_digits, atoi(gen_dig_type), atoi(gen_dig_scheme)); 01335 01336 gen_name = pbx_builtin_getvar_helper(ast, "SS7_GENERIC_NAME"); 01337 if (gen_name) 01338 isup_set_generic_name(p->ss7call, gen_name, GEN_NAME_TYPE_CALLING_NAME, GEN_NAME_AVAIL_AVAILABLE, GEN_NAME_PRES_ALLOWED); 01339 01340 jip_digits = pbx_builtin_getvar_helper(ast, "SS7_JIP"); 01341 if (jip_digits) 01342 isup_set_jip_digits(p->ss7call, jip_digits); 01343 01344 lspi_ident = pbx_builtin_getvar_helper(ast, "SS7_LSPI_IDENT"); 01345 if (lspi_ident) 01346 isup_set_lspi(p->ss7call, lspi_ident, 0x18, 0x7, 0x00); 01347 01348 rlt_flag = pbx_builtin_getvar_helper(ast, "SS7_RLT_ON"); 01349 if ((rlt_flag) && ((strncmp("NO", rlt_flag, strlen(rlt_flag))) != 0 )) { 01350 isup_set_lspi(p->ss7call, rlt_flag, 0x18, 0x7, 0x00); /* Setting for Nortel DMS-250/500 */ 01351 } 01352 01353 call_ref_id = pbx_builtin_getvar_helper(ast, "SS7_CALLREF_IDENT"); 01354 call_ref_pc = pbx_builtin_getvar_helper(ast, "SS7_CALLREF_PC"); 01355 if (call_ref_id && call_ref_pc) { 01356 isup_set_callref(p->ss7call, atoi(call_ref_id), 01357 call_ref_pc ? atoi(call_ref_pc) : 0); 01358 } 01359 01360 send_far = pbx_builtin_getvar_helper(ast, "SS7_SEND_FAR"); 01361 if ((send_far) && ((strncmp("NO", send_far, strlen(send_far))) != 0 )) 01362 (isup_far(p->ss7->ss7, p->ss7call)); 01363 01364 isup_iam(p->ss7->ss7, p->ss7call); 01365 sig_ss7_set_dialing(p, 1); 01366 ast_setstate(ast, AST_STATE_DIALING); 01367 ss7_rel(p->ss7); 01368 return 0; 01369 }
void sig_ss7_chan_delete | ( | struct sig_ss7_chan * | doomed | ) |
Delete the sig_ss7 private channel structure.
doomed | sig_ss7 private channel structure to delete. |
Definition at line 1591 of file sig_ss7.c.
References ast_free.
Referenced by destroy_dahdi_pvt().
01592 { 01593 ast_free(doomed); 01594 }
struct sig_ss7_chan* sig_ss7_chan_new | ( | void * | pvt_data, | |
struct sig_ss7_callback * | callback, | |||
struct sig_ss7_linkset * | ss7 | |||
) |
Create a new sig_ss7 private channel structure.
pvt_data | Upper layer private data structure. | |
callback | Callbacks to the upper layer. | |
ss7 | Controlling linkset for the channel. |
sig_ss7_chan | on success. | |
NULL | on error. |
Definition at line 1607 of file sig_ss7.c.
References ast_calloc, and sig_ss7_chan::ss7.
01608 { 01609 struct sig_ss7_chan *pvt; 01610 01611 pvt = ast_calloc(1, sizeof(*pvt)); 01612 if (!pvt) { 01613 return pvt; 01614 } 01615 01616 pvt->calls = callback; 01617 pvt->chan_pvt = pvt_data; 01618 pvt->ss7 = ss7; 01619 01620 return pvt; 01621 }
void sig_ss7_fixup | ( | struct ast_channel * | oldchan, | |
struct ast_channel * | newchan, | |||
struct sig_ss7_chan * | pchan | |||
) |
Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links.
oldchan | Old channel pointer to replace. | |
newchan | New channel pointer to set. | |
pchan | Signaling private structure pointer. |
Definition at line 1458 of file sig_ss7.c.
References sig_ss7_chan::owner.
static void sig_ss7_handle_link_exception | ( | struct sig_ss7_linkset * | linkset, | |
int | which | |||
) | [static] |
Definition at line 225 of file sig_ss7.c.
References sig_ss7_linkset::calls, and sig_ss7_callback::handle_link_exception.
00226 { 00227 if (linkset->calls->handle_link_exception) { 00228 linkset->calls->handle_link_exception(linkset, which); 00229 } 00230 }
int sig_ss7_hangup | ( | struct sig_ss7_chan * | p, | |
struct ast_channel * | ast | |||
) |
SS7 hangup channel.
p | Signaling private structure pointer. | |
ast | Asterisk channel structure pointer. |
0 | on success. | |
-1 | on error. |
Definition at line 1381 of file sig_ss7.c.
References sig_ss7_chan::alerting, sig_ss7_chan::alreadyhungup, ast_log(), cause, sig_ss7_chan::cic, sig_ss7_chan::exten, ast_channel::hangupcause, LOG_WARNING, sig_ss7_chan::outgoing, sig_ss7_chan::owner, pbx_builtin_getvar_helper(), sig_ss7_chan::proceeding, sig_ss7_chan::progress, sig_ss7_chan::rlt, sig_ss7_set_dialing(), sig_ss7_chan::ss7, sig_ss7_linkset::ss7, ss7_grab(), ss7_rel(), sig_ss7_chan::ss7call, and ast_channel::tech_pvt.
Referenced by dahdi_hangup().
01382 { 01383 int res = 0; 01384 01385 if (!ast->tech_pvt) { 01386 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n"); 01387 return 0; 01388 } 01389 01390 p->owner = NULL; 01391 sig_ss7_set_dialing(p, 0); 01392 p->outgoing = 0; 01393 p->proceeding = 0; 01394 p->progress = 0; 01395 p->alerting = 0; 01396 p->rlt = 0; 01397 p->exten[0] = '\0'; 01398 /* Perform low level hangup if no owner left */ 01399 if (p->ss7call) { 01400 if (!ss7_grab(p, p->ss7)) { 01401 if (!p->alreadyhungup) { 01402 const char *cause = pbx_builtin_getvar_helper(ast,"SS7_CAUSE"); 01403 int icause = ast->hangupcause ? ast->hangupcause : -1; 01404 01405 if (cause) { 01406 if (atoi(cause)) 01407 icause = atoi(cause); 01408 } 01409 isup_rel(p->ss7->ss7, p->ss7call, icause); 01410 ss7_rel(p->ss7); 01411 p->alreadyhungup = 1; 01412 } else 01413 ast_log(LOG_WARNING, "Trying to hangup twice!\n"); 01414 } else { 01415 ast_log(LOG_WARNING, "Unable to grab SS7 on CIC %d\n", p->cic); 01416 res = -1; 01417 } 01418 } 01419 01420 return res; 01421 }
int sig_ss7_indicate | ( | struct sig_ss7_chan * | p, | |
struct ast_channel * | chan, | |||
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) |
SS7 answer channel.
p | Signaling private structure pointer. | |
chan | Asterisk channel structure pointer. | |
condition | AST control frame subtype. | |
data | AST control frame payload contents. | |
datalen | Length of payload contents. |
0 | on success. | |
-1 | on error or indication condition not handled. |
Definition at line 1478 of file sig_ss7.c.
References ast_channel::_state, sig_ss7_chan::alerting, AST_CAUSE_CONGESTION, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, ast_debug, ast_moh_start(), ast_moh_stop(), ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_channel::hangupcause, sig_ss7_chan::mohinterpret, ast_channel::name, sig_ss7_chan::outgoing, sig_ss7_chan::proceeding, sig_ss7_chan::progress, sig_ss7_chan::rlt, sig_ss7_play_tone(), sig_ss7_set_echocanceller(), SIG_SS7_TONE_BUSY, SIG_SS7_TONE_RINGTONE, sig_ss7_chan::ss7, sig_ss7_linkset::ss7, ss7_grab(), ss7_rel(), and sig_ss7_chan::ss7call.
Referenced by dahdi_indicate().
01479 { 01480 int res = -1; 01481 01482 switch (condition) { 01483 case AST_CONTROL_BUSY: 01484 res = sig_ss7_play_tone(p, SIG_SS7_TONE_BUSY); 01485 break; 01486 case AST_CONTROL_RINGING: 01487 if ((!p->alerting) && p->ss7 && !p->outgoing && (chan->_state != AST_STATE_UP)) { 01488 if (p->ss7->ss7) { 01489 ss7_grab(p, p->ss7); 01490 01491 if ((isup_far(p->ss7->ss7, p->ss7call)) != -1) 01492 p->rlt = 1; 01493 if (p->rlt != 1) /* No need to send CPG if call will be RELEASE */ 01494 isup_cpg(p->ss7->ss7, p->ss7call, CPG_EVENT_ALERTING); 01495 p->alerting = 1; 01496 ss7_rel(p->ss7); 01497 } 01498 } 01499 01500 res = sig_ss7_play_tone(p, SIG_SS7_TONE_RINGTONE); 01501 01502 if (chan->_state != AST_STATE_UP && chan->_state != AST_STATE_RING) { 01503 ast_setstate(chan, AST_STATE_RINGING); 01504 } 01505 break; 01506 case AST_CONTROL_PROCEEDING: 01507 ast_debug(1,"Received AST_CONTROL_PROCEEDING on %s\n",chan->name); 01508 /* This IF sends the FAR for an answered ALEG call */ 01509 if (chan->_state == AST_STATE_UP && (p->rlt != 1)){ 01510 if ((isup_far(p->ss7->ss7, p->ss7call)) != -1) 01511 p->rlt = 1; 01512 } 01513 01514 if (!p->proceeding && p->ss7 && !p->outgoing) { 01515 if (p->ss7->ss7) { 01516 ss7_grab(p, p->ss7); 01517 isup_acm(p->ss7->ss7, p->ss7call); 01518 p->proceeding = 1; 01519 ss7_rel(p->ss7); 01520 } 01521 } 01522 /* don't continue in ast_indicate */ 01523 res = 0; 01524 break; 01525 case AST_CONTROL_PROGRESS: 01526 ast_debug(1,"Received AST_CONTROL_PROGRESS on %s\n",chan->name); 01527 if (!p->progress && p->ss7 && !p->outgoing) { 01528 if (p->ss7->ss7) { 01529 ss7_grab(p, p->ss7); 01530 isup_cpg(p->ss7->ss7, p->ss7call, CPG_EVENT_INBANDINFO); 01531 p->progress = 1; 01532 ss7_rel(p->ss7); 01533 /* enable echo canceler here on SS7 calls */ 01534 sig_ss7_set_echocanceller(p, 1); 01535 } 01536 } 01537 /* don't continue in ast_indicate */ 01538 res = 0; 01539 break; 01540 case AST_CONTROL_CONGESTION: 01541 chan->hangupcause = AST_CAUSE_CONGESTION; 01542 break; 01543 case AST_CONTROL_HOLD: 01544 ast_moh_start(chan, data, p->mohinterpret); 01545 break; 01546 case AST_CONTROL_UNHOLD: 01547 ast_moh_stop(chan); 01548 break; 01549 case AST_CONTROL_SRCUPDATE: 01550 res = 0; 01551 break; 01552 case -1: 01553 res = sig_ss7_play_tone(p, -1); 01554 break; 01555 } 01556 return res; 01557 }
void sig_ss7_init_linkset | ( | struct sig_ss7_linkset * | ss7 | ) |
Initialize the SS7 linkset control.
ss7 | sig_ss7 SS7 control structure. |
Definition at line 1631 of file sig_ss7.c.
References ARRAY_LEN, ast_mutex_init, AST_PTHREADT_NULL, and sig_ss7_chan::ss7.
Referenced by load_module().
01632 { 01633 int idx; 01634 01635 memset(ss7, 0, sizeof(*ss7)); 01636 01637 ast_mutex_init(&ss7->lock); 01638 01639 ss7->master = AST_PTHREADT_NULL; 01640 for (idx = 0; idx < ARRAY_LEN(ss7->fds); ++idx) { 01641 ss7->fds[idx] = -1; 01642 } 01643 }
void sig_ss7_link_alarm | ( | struct sig_ss7_linkset * | linkset, | |
int | which | |||
) |
Notify the SS7 layer that the link is in alarm.
linkset | Controlling linkset for the channel. | |
which | Link index of the signaling channel. |
Definition at line 1119 of file sig_ss7.c.
References sig_ss7_linkset::fds, sig_ss7_linkset::linkstate, LINKSTATE_DOWN, LINKSTATE_INALARM, LINKSTATE_UP, and sig_ss7_linkset::ss7.
Referenced by my_handle_link_exception().
01120 { 01121 linkset->linkstate[which] |= (LINKSTATE_DOWN | LINKSTATE_INALARM); 01122 linkset->linkstate[which] &= ~LINKSTATE_UP; 01123 ss7_link_alarm(linkset->ss7, linkset->fds[which]); 01124 }
void sig_ss7_link_noalarm | ( | struct sig_ss7_linkset * | linkset, | |
int | which | |||
) |
Notify the SS7 layer that the link is no longer in alarm.
linkset | Controlling linkset for the channel. | |
which | Link index of the signaling channel. |
Definition at line 1135 of file sig_ss7.c.
References sig_ss7_linkset::fds, sig_ss7_linkset::linkstate, LINKSTATE_DOWN, LINKSTATE_INALARM, LINKSTATE_STARTING, and sig_ss7_linkset::ss7.
Referenced by my_handle_link_exception().
01136 { 01137 linkset->linkstate[which] &= ~(LINKSTATE_INALARM | LINKSTATE_DOWN); 01138 linkset->linkstate[which] |= LINKSTATE_STARTING; 01139 ss7_link_noalarm(linkset->ss7, linkset->fds[which]); 01140 }
static void sig_ss7_lock_owner | ( | struct sig_ss7_linkset * | ss7, | |
int | chanpos | |||
) | [static] |
Definition at line 245 of file sig_ss7.c.
References ast_channel_trylock, sig_ss7_chan::owner, and sig_ss7_linkset::pvts.
Referenced by sig_ss7_queue_frame().
00246 { 00247 for (;;) { 00248 if (!ss7->pvts[chanpos]->owner) { 00249 /* There is no owner lock to get. */ 00250 break; 00251 } 00252 if (!ast_channel_trylock(ss7->pvts[chanpos]->owner)) { 00253 /* We got the lock */ 00254 break; 00255 } 00256 /* We must unlock the SS7 to avoid the possibility of a deadlock */ 00257 ast_mutex_unlock(&ss7->lock); 00258 SIG_SS7_DEADLOCK_AVOIDANCE(ss7->pvts[chanpos]); 00259 ast_mutex_lock(&ss7->lock); 00260 } 00261 }
static void sig_ss7_lock_private | ( | struct sig_ss7_chan * | p | ) | [static] |
Definition at line 60 of file sig_ss7.c.
References sig_ss7_chan::calls, sig_ss7_chan::chan_pvt, and sig_ss7_callback::lock_private.
Referenced by ss7_hangup_cics().
00061 { 00062 if (p->calls->lock_private) { 00063 p->calls->lock_private(p->chan_pvt); 00064 } 00065 }
static void sig_ss7_loopback | ( | struct sig_ss7_chan * | p, | |
int | enable | |||
) | [static] |
Definition at line 191 of file sig_ss7.c.
References sig_ss7_chan::calls, sig_ss7_chan::chan_pvt, sig_ss7_chan::loopedback, and sig_ss7_callback::set_loopback.
00192 { 00193 if (p->loopedback != enable) { 00194 p->loopedback = enable; 00195 if (p->calls->set_loopback) { 00196 p->calls->set_loopback(p->chan_pvt, enable); 00197 } 00198 } 00199 }
static struct ast_channel* sig_ss7_new_ast_channel | ( | struct sig_ss7_chan * | p, | |
int | state, | |||
int | ulaw, | |||
int | transfercapability, | |||
char * | exten, | |||
const struct ast_channel * | requestor | |||
) | [static] |
Definition at line 201 of file sig_ss7.c.
References sig_ss7_chan::alreadyhungup, AST_TRANS_CAP_DIGITAL, ast_transfercapability2str(), sig_ss7_chan::calls, sig_ss7_chan::chan_pvt, sig_ss7_callback::new_ast_channel, sig_ss7_chan::owner, pbx_builtin_setvar_helper(), sig_ss7_set_digital(), and ast_channel::transfercapability.
Referenced by sig_ss7_request(), and ss7_start_call().
00202 { 00203 struct ast_channel *ast; 00204 00205 if (p->calls->new_ast_channel) { 00206 ast = p->calls->new_ast_channel(p->chan_pvt, state, ulaw, exten, requestor); 00207 } else { 00208 return NULL; 00209 } 00210 00211 if (!p->owner) { 00212 p->owner = ast; 00213 } 00214 p->alreadyhungup = 0; 00215 ast->transfercapability = transfercapability; 00216 pbx_builtin_setvar_helper(ast, "TRANSFERCAPABILITY", 00217 ast_transfercapability2str(transfercapability)); 00218 if (transfercapability & AST_TRANS_CAP_DIGITAL) { 00219 sig_ss7_set_digital(p, 1); 00220 } 00221 00222 return ast; 00223 }
static int sig_ss7_play_tone | ( | struct sig_ss7_chan * | p, | |
enum sig_ss7_tone | tone | |||
) | [static] |
Definition at line 171 of file sig_ss7.c.
References sig_ss7_chan::calls, sig_ss7_chan::chan_pvt, and sig_ss7_callback::play_tone.
Referenced by sig_ss7_indicate().
00172 { 00173 int res; 00174 00175 if (p->calls->play_tone) { 00176 res = p->calls->play_tone(p->chan_pvt, tone); 00177 } else { 00178 res = -1; 00179 } 00180 return res; 00181 }
static void sig_ss7_queue_control | ( | struct sig_ss7_linkset * | ss7, | |
int | chanpos, | |||
int | subclass | |||
) | [static] |
Definition at line 300 of file sig_ss7.c.
References AST_FRAME_CONTROL, sig_ss7_chan::calls, sig_ss7_chan::chan_pvt, f, sig_ss7_linkset::pvts, sig_ss7_callback::queue_control, sig_ss7_queue_frame(), and sig_ss7_chan::ss7.
00301 { 00302 struct ast_frame f = {AST_FRAME_CONTROL, }; 00303 struct sig_ss7_chan *p = ss7->pvts[chanpos]; 00304 00305 if (p->calls->queue_control) { 00306 p->calls->queue_control(p->chan_pvt, subclass); 00307 } 00308 00309 f.subclass.integer = subclass; 00310 sig_ss7_queue_frame(ss7, chanpos, &f); 00311 }
static void sig_ss7_queue_frame | ( | struct sig_ss7_linkset * | ss7, | |
int | chanpos, | |||
struct ast_frame * | frame | |||
) | [static] |
Definition at line 277 of file sig_ss7.c.
References ast_channel_unlock, ast_queue_frame(), sig_ss7_chan::owner, sig_ss7_linkset::pvts, and sig_ss7_lock_owner().
Referenced by sig_ss7_queue_control().
00278 { 00279 sig_ss7_lock_owner(ss7, chanpos); 00280 if (ss7->pvts[chanpos]->owner) { 00281 ast_queue_frame(ss7->pvts[chanpos]->owner, frame); 00282 ast_channel_unlock(ss7->pvts[chanpos]->owner); 00283 } 00284 }
struct ast_channel* sig_ss7_request | ( | struct sig_ss7_chan * | p, | |
enum sig_ss7_law | law, | |||
const struct ast_channel * | requestor, | |||
int | transfercapability | |||
) |
SS7 channel request.
p | Signaling private structure pointer. | |
law | Companding law preferred | |
requestor | Asterisk channel requesting a channel to dial (Can be NULL) | |
transfercapability |
ast_channel | on success. | |
NULL | on error. |
Definition at line 1571 of file sig_ss7.c.
References AST_STATE_RESERVED, sig_ss7_chan::exten, sig_ss7_chan::outgoing, and sig_ss7_new_ast_channel().
Referenced by dahdi_request().
01572 { 01573 struct ast_channel *ast; 01574 01575 p->outgoing = 1; 01576 ast = sig_ss7_new_ast_channel(p, AST_STATE_RESERVED, law, transfercapability, p->exten, requestor); 01577 if (!ast) { 01578 p->outgoing = 0; 01579 } 01580 return ast; 01581 }
void sig_ss7_set_alarm | ( | struct sig_ss7_chan * | p, | |
int | in_alarm | |||
) |
Definition at line 67 of file sig_ss7.c.
References sig_ss7_chan::calls, sig_ss7_chan::chan_pvt, sig_ss7_chan::inalarm, and sig_ss7_callback::set_alarm.
Referenced by dahdi_handle_event(), and handle_init_event().
00068 { 00069 p->inalarm = in_alarm; 00070 if (p->calls->set_alarm) { 00071 p->calls->set_alarm(p->chan_pvt, in_alarm); 00072 } 00073 }
static void sig_ss7_set_caller_id | ( | struct sig_ss7_chan * | p | ) | [static] |
Definition at line 121 of file sig_ss7.c.
References ast_party_caller::ani, ast_party_caller::ani2, ast_party_caller_init(), ast_strlen_zero(), sig_ss7_chan::callingpres, sig_ss7_chan::calls, sig_ss7_chan::chan_pvt, sig_ss7_chan::cid_ani, sig_ss7_chan::cid_ani2, sig_ss7_chan::cid_name, sig_ss7_chan::cid_num, sig_ss7_chan::cid_subaddr, sig_ss7_chan::cid_ton, ast_party_caller::id, ast_party_id::name, ast_party_id::number, ast_party_number::plan, ast_party_number::presentation, ast_party_name::presentation, sig_ss7_callback::set_callerid, ast_party_subaddress::str, ast_party_number::str, ast_party_name::str, ast_party_id::subaddress, ast_party_subaddress::valid, ast_party_number::valid, and ast_party_name::valid.
00122 { 00123 struct ast_party_caller caller; 00124 00125 if (p->calls->set_callerid) { 00126 ast_party_caller_init(&caller); 00127 00128 caller.id.name.str = p->cid_name; 00129 caller.id.name.presentation = p->callingpres; 00130 caller.id.name.valid = 1; 00131 00132 caller.id.number.str = p->cid_num; 00133 caller.id.number.plan = p->cid_ton; 00134 caller.id.number.presentation = p->callingpres; 00135 caller.id.number.valid = 1; 00136 00137 if (!ast_strlen_zero(p->cid_subaddr)) { 00138 caller.id.subaddress.valid = 1; 00139 //caller.id.subaddress.type = 0;/* nsap */ 00140 //caller.id.subaddress.odd_even_indicator = 0; 00141 caller.id.subaddress.str = p->cid_subaddr; 00142 } 00143 00144 caller.ani.number.str = p->cid_ani; 00145 //caller.ani.number.plan = p->xxx; 00146 //caller.ani.number.presentation = p->xxx; 00147 caller.ani.number.valid = 1; 00148 00149 caller.ani2 = p->cid_ani2; 00150 p->calls->set_callerid(p->chan_pvt, &caller); 00151 } 00152 }
static void sig_ss7_set_dialing | ( | struct sig_ss7_chan * | p, | |
int | is_dialing | |||
) | [static] |
Definition at line 75 of file sig_ss7.c.
References sig_ss7_chan::calls, sig_ss7_chan::chan_pvt, and sig_ss7_callback::set_dialing.
Referenced by sig_ss7_call(), and sig_ss7_hangup().
00076 { 00077 if (p->calls->set_dialing) { 00078 p->calls->set_dialing(p->chan_pvt, is_dialing); 00079 } 00080 }
static void sig_ss7_set_digital | ( | struct sig_ss7_chan * | p, | |
int | is_digital | |||
) | [static] |
Definition at line 82 of file sig_ss7.c.
References sig_ss7_chan::calls, sig_ss7_chan::chan_pvt, and sig_ss7_callback::set_digital.
Referenced by sig_ss7_new_ast_channel().
00083 { 00084 if (p->calls->set_digital) { 00085 p->calls->set_digital(p->chan_pvt, is_digital); 00086 } 00087 }
static void sig_ss7_set_dnid | ( | struct sig_ss7_chan * | p, | |
const char * | dnid | |||
) | [static] |
Definition at line 164 of file sig_ss7.c.
References sig_ss7_chan::calls, sig_ss7_chan::chan_pvt, and sig_ss7_callback::set_dnid.
00165 { 00166 if (p->calls->set_dnid) { 00167 p->calls->set_dnid(p->chan_pvt, dnid); 00168 } 00169 }
static int sig_ss7_set_echocanceller | ( | struct sig_ss7_chan * | p, | |
int | enable | |||
) | [static] |
Definition at line 183 of file sig_ss7.c.
References sig_ss7_chan::calls, sig_ss7_chan::chan_pvt, and sig_ss7_callback::set_echocanceller.
Referenced by sig_ss7_indicate(), and ss7_start_call().
00184 { 00185 if (p->calls->set_echocanceller) { 00186 return p->calls->set_echocanceller(p->chan_pvt, enable); 00187 } 00188 return -1; 00189 }
static void sig_ss7_set_inservice | ( | struct sig_ss7_chan * | p, | |
int | is_inservice | |||
) | [static] |
Definition at line 89 of file sig_ss7.c.
References sig_ss7_chan::calls, sig_ss7_chan::chan_pvt, and sig_ss7_callback::set_inservice.
Referenced by ss7_inservice().
00090 { 00091 if (p->calls->set_inservice) { 00092 p->calls->set_inservice(p->chan_pvt, is_inservice); 00093 } 00094 }
static void sig_ss7_set_locallyblocked | ( | struct sig_ss7_chan * | p, | |
int | is_blocked | |||
) | [static] |
Definition at line 96 of file sig_ss7.c.
References sig_ss7_chan::calls, sig_ss7_chan::chan_pvt, sig_ss7_chan::locallyblocked, and sig_ss7_callback::set_locallyblocked.
00097 { 00098 p->locallyblocked = is_blocked; 00099 if (p->calls->set_locallyblocked) { 00100 p->calls->set_locallyblocked(p->chan_pvt, is_blocked); 00101 } 00102 }
static void sig_ss7_set_remotelyblocked | ( | struct sig_ss7_chan * | p, | |
int | is_blocked | |||
) | [static] |
Definition at line 104 of file sig_ss7.c.
References sig_ss7_chan::calls, sig_ss7_chan::chan_pvt, sig_ss7_chan::remotelyblocked, and sig_ss7_callback::set_remotelyblocked.
Referenced by ss7_block_cics().
00105 { 00106 p->remotelyblocked = is_blocked; 00107 if (p->calls->set_remotelyblocked) { 00108 p->calls->set_remotelyblocked(p->chan_pvt, is_blocked); 00109 } 00110 }
static void sig_ss7_unlock_private | ( | struct sig_ss7_chan * | p | ) | [static] |
Definition at line 53 of file sig_ss7.c.
References sig_ss7_chan::calls, sig_ss7_chan::chan_pvt, and sig_ss7_callback::unlock_private.
Referenced by ss7_hangup_cics().
00054 { 00055 if (p->calls->unlock_private) { 00056 p->calls->unlock_private(p->chan_pvt); 00057 } 00058 }
static void ss7_apply_plan_to_number | ( | char * | buf, | |
size_t | size, | |||
const struct sig_ss7_linkset * | ss7, | |||
const char * | number, | |||
const unsigned | nai | |||
) | [static] |
Definition at line 549 of file sig_ss7.c.
References ast_strlen_zero(), sig_ss7_linkset::internationalprefix, sig_ss7_linkset::nationalprefix, sig_ss7_linkset::subscriberprefix, and sig_ss7_linkset::unknownprefix.
00550 { 00551 if (ast_strlen_zero(number)) { /* make sure a number exists so prefix isn't placed on an empty string */ 00552 if (size) { 00553 *buf = '\0'; 00554 } 00555 return; 00556 } 00557 switch (nai) { 00558 case SS7_NAI_INTERNATIONAL: 00559 snprintf(buf, size, "%s%s", ss7->internationalprefix, number); 00560 break; 00561 case SS7_NAI_NATIONAL: 00562 snprintf(buf, size, "%s%s", ss7->nationalprefix, number); 00563 break; 00564 case SS7_NAI_SUBSCRIBER: 00565 snprintf(buf, size, "%s%s", ss7->subscriberprefix, number); 00566 break; 00567 case SS7_NAI_UNKNOWN: 00568 snprintf(buf, size, "%s%s", ss7->unknownprefix, number); 00569 break; 00570 default: 00571 snprintf(buf, size, "%s", number); 00572 break; 00573 } 00574 }
static void ss7_block_cics | ( | struct sig_ss7_linkset * | linkset, | |
int | startcic, | |||
int | endcic, | |||
unsigned int | dpc, | |||
unsigned char | state[], | |||
int | block | |||
) | [inline, static] |
Definition at line 372 of file sig_ss7.c.
References sig_ss7_chan::cic, sig_ss7_chan::dpc, sig_ss7_linkset::numchans, sig_ss7_linkset::pvts, and sig_ss7_set_remotelyblocked().
00373 { 00374 int i; 00375 00376 for (i = 0; i < linkset->numchans; i++) { 00377 if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic)))) { 00378 if (state) { 00379 if (state[i]) 00380 sig_ss7_set_remotelyblocked(linkset->pvts[i], block); 00381 } else 00382 sig_ss7_set_remotelyblocked(linkset->pvts[i], block); 00383 } 00384 } 00385 }
static int ss7_find_cic | ( | struct sig_ss7_linkset * | linkset, | |
int | cic, | |||
unsigned int | dpc | |||
) | [static] |
Definition at line 313 of file sig_ss7.c.
References sig_ss7_chan::cic, sig_ss7_chan::dpc, sig_ss7_linkset::numchans, and sig_ss7_linkset::pvts.
00314 { 00315 int i; 00316 int winner = -1; 00317 for (i = 0; i < linkset->numchans; i++) { 00318 if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && linkset->pvts[i]->cic == cic)) { 00319 winner = i; 00320 break; 00321 } 00322 } 00323 return winner; 00324 }
static int ss7_grab | ( | struct sig_ss7_chan * | pvt, | |
struct sig_ss7_linkset * | ss7 | |||
) | [inline, static] |
Definition at line 1094 of file sig_ss7.c.
References ast_mutex_trylock, AST_PTHREADT_NULL, sig_ss7_linkset::lock, sig_ss7_linkset::master, and SIG_SS7_DEADLOCK_AVOIDANCE.
Referenced by sig_ss7_answer(), sig_ss7_call(), sig_ss7_hangup(), and sig_ss7_indicate().
01095 { 01096 int res; 01097 /* Grab the lock first */ 01098 do { 01099 res = ast_mutex_trylock(&ss7->lock); 01100 if (res) { 01101 SIG_SS7_DEADLOCK_AVOIDANCE(pvt); 01102 } 01103 } while (res); 01104 /* Then break the poll */ 01105 if (ss7->master != AST_PTHREADT_NULL) 01106 pthread_kill(ss7->master, SIGURG); 01107 return 0; 01108 }
static void ss7_handle_cqm | ( | struct sig_ss7_linkset * | linkset, | |
int | startcic, | |||
int | endcic, | |||
unsigned int | dpc | |||
) | [static] |
Definition at line 326 of file sig_ss7.c.
References sig_ss7_chan::cic, sig_ss7_chan::dpc, sig_ss7_chan::locallyblocked, sig_ss7_linkset::numchans, sig_ss7_chan::outgoing, sig_ss7_linkset::pvts, sig_ss7_chan::remotelyblocked, sig_ss7_chan::ss7call, and status.
00327 { 00328 unsigned char status[32]; 00329 struct sig_ss7_chan *p = NULL; 00330 int i, offset; 00331 00332 for (i = 0; i < linkset->numchans; i++) { 00333 if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic)))) { 00334 p = linkset->pvts[i]; 00335 offset = p->cic - startcic; 00336 status[offset] = 0; 00337 if (p->locallyblocked) 00338 status[offset] |= (1 << 0) | (1 << 4); 00339 if (p->remotelyblocked) 00340 status[offset] |= (1 << 1) | (1 << 5); 00341 if (p->ss7call) { 00342 if (p->outgoing) 00343 status[offset] |= (1 << 3); 00344 else 00345 status[offset] |= (1 << 2); 00346 } else 00347 status[offset] |= 0x3 << 2; 00348 } 00349 } 00350 00351 if (p) 00352 isup_cqr(linkset->ss7, startcic, endcic, dpc, status); 00353 else 00354 ast_log(LOG_WARNING, "Could not find any equipped circuits within CQM CICs\n"); 00355 00356 }
static void ss7_hangup_cics | ( | struct sig_ss7_linkset * | linkset, | |
int | startcic, | |||
int | endcic, | |||
unsigned int | dpc | |||
) | [inline, static] |
Definition at line 358 of file sig_ss7.c.
References ast_channel::_softhangup, AST_SOFTHANGUP_DEV, sig_ss7_chan::cic, sig_ss7_chan::dpc, sig_ss7_linkset::numchans, sig_ss7_chan::owner, sig_ss7_linkset::pvts, sig_ss7_lock_private(), and sig_ss7_unlock_private().
00359 { 00360 int i; 00361 00362 for (i = 0; i < linkset->numchans; i++) { 00363 if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic)))) { 00364 sig_ss7_lock_private(linkset->pvts[i]); 00365 if (linkset->pvts[i]->owner) 00366 linkset->pvts[i]->owner->_softhangup |= AST_SOFTHANGUP_DEV; 00367 sig_ss7_unlock_private(linkset->pvts[i]); 00368 } 00369 } 00370 }
static void ss7_inservice | ( | struct sig_ss7_linkset * | linkset, | |
int | startcic, | |||
int | endcic, | |||
unsigned int | dpc | |||
) | [static] |
Definition at line 387 of file sig_ss7.c.
References sig_ss7_chan::cic, sig_ss7_chan::dpc, sig_ss7_linkset::numchans, sig_ss7_linkset::pvts, and sig_ss7_set_inservice().
00388 { 00389 int i; 00390 00391 for (i = 0; i < linkset->numchans; i++) { 00392 if (linkset->pvts[i] && (linkset->pvts[i]->dpc == dpc && ((linkset->pvts[i]->cic >= startcic) && (linkset->pvts[i]->cic <= endcic)))) 00393 sig_ss7_set_inservice(linkset->pvts[i], 1); 00394 } 00395 }
void* ss7_linkset | ( | void * | data | ) |
Definition at line 582 of file sig_ss7.c.
References ast_mutex_lock, ast_tvnow(), sig_ss7_linkset::lock, SIG_SS7_DEBUG_DEFAULT, sig_ss7_linkset::ss7, and tv.
00583 { 00584 int res, i; 00585 struct timeval *next = NULL, tv; 00586 struct sig_ss7_linkset *linkset = (struct sig_ss7_linkset *) data; 00587 struct ss7 *ss7 = linkset->ss7; 00588 ss7_event *e = NULL; 00589 struct sig_ss7_chan *p; 00590 int chanpos; 00591 struct pollfd pollers[SIG_SS7_NUM_DCHANS]; 00592 int cic; 00593 unsigned int dpc; 00594 int nextms = 0; 00595 00596 ss7_set_debug(ss7, SIG_SS7_DEBUG_DEFAULT); 00597 ss7_start(ss7); 00598 00599 for (;;) { 00600 ast_mutex_lock(&linkset->lock); 00601 if ((next = ss7_schedule_next(ss7))) { 00602 tv = ast_tvnow(); 00603 tv.tv_sec = next->tv_sec - tv.tv_sec; 00604 tv.tv_usec = next->tv_usec - tv.tv_usec; 00605 if (tv.tv_usec < 0) { 00606 tv.tv_usec += 1000000; 00607 tv.tv_sec -= 1; 00608 } 00609 if (tv.tv_sec < 0) { 00610 tv.tv_sec = 0; 00611 tv.tv_usec = 0; 00612 } 00613 nextms = tv.tv_sec * 1000; 00614 nextms += tv.tv_usec / 1000; 00615 } 00616 ast_mutex_unlock(&linkset->lock); 00617 00618 for (i = 0; i < linkset->numsigchans; i++) { 00619 pollers[i].fd = linkset->fds[i]; 00620 pollers[i].events = ss7_pollflags(ss7, linkset->fds[i]); 00621 pollers[i].revents = 0; 00622 } 00623 00624 res = poll(pollers, linkset->numsigchans, nextms); 00625 if ((res < 0) && (errno != EINTR)) { 00626 ast_log(LOG_ERROR, "poll(%s)\n", strerror(errno)); 00627 } else if (!res) { 00628 ast_mutex_lock(&linkset->lock); 00629 ss7_schedule_run(ss7); 00630 ast_mutex_unlock(&linkset->lock); 00631 continue; 00632 } 00633 00634 ast_mutex_lock(&linkset->lock); 00635 for (i = 0; i < linkset->numsigchans; i++) { 00636 if (pollers[i].revents & POLLPRI) { 00637 sig_ss7_handle_link_exception(linkset, i); 00638 } 00639 if (pollers[i].revents & POLLIN) { 00640 res = ss7_read(ss7, pollers[i].fd); 00641 } 00642 if (pollers[i].revents & POLLOUT) { 00643 res = ss7_write(ss7, pollers[i].fd); 00644 if (res < 0) { 00645 ast_debug(1, "Error in write %s\n", strerror(errno)); 00646 } 00647 } 00648 } 00649 00650 while ((e = ss7_check_event(ss7))) { 00651 switch (e->e) { 00652 case SS7_EVENT_UP: 00653 if (linkset->state != LINKSET_STATE_UP) { 00654 ast_verbose("--- SS7 Up ---\n"); 00655 ss7_reset_linkset(linkset); 00656 } 00657 linkset->state = LINKSET_STATE_UP; 00658 break; 00659 case SS7_EVENT_DOWN: 00660 ast_verbose("--- SS7 Down ---\n"); 00661 linkset->state = LINKSET_STATE_DOWN; 00662 for (i = 0; i < linkset->numchans; i++) { 00663 p = linkset->pvts[i]; 00664 if (p) { 00665 sig_ss7_set_alarm(p, 1); 00666 } 00667 } 00668 break; 00669 case MTP2_LINK_UP: 00670 ast_verbose("MTP2 link up (SLC %d)\n", e->gen.data); 00671 break; 00672 case MTP2_LINK_DOWN: 00673 ast_log(LOG_WARNING, "MTP2 link down (SLC %d)\n", e->gen.data); 00674 break; 00675 case ISUP_EVENT_CPG: 00676 chanpos = ss7_find_cic(linkset, e->cpg.cic, e->cpg.opc); 00677 if (chanpos < 0) { 00678 ast_log(LOG_WARNING, "CPG on unconfigured CIC %d\n", e->cpg.cic); 00679 break; 00680 } 00681 p = linkset->pvts[chanpos]; 00682 sig_ss7_lock_private(p); 00683 switch (e->cpg.event) { 00684 case CPG_EVENT_ALERTING: 00685 p->alerting = 1; 00686 sig_ss7_queue_control(linkset, chanpos, AST_CONTROL_RINGING); 00687 break; 00688 case CPG_EVENT_PROGRESS: 00689 case CPG_EVENT_INBANDINFO: 00690 { 00691 ast_debug(1, "Queuing frame PROGRESS on CIC %d\n", p->cic); 00692 sig_ss7_queue_control(linkset, chanpos, AST_CONTROL_PROGRESS); 00693 p->progress = 1; 00694 sig_ss7_set_dialing(p, 0); 00695 #if 0 /* This code no longer seems to be necessary so I did not convert it. */ 00696 if (p->dsp && p->dsp_features) { 00697 ast_dsp_set_features(p->dsp, p->dsp_features); 00698 p->dsp_features = 0; 00699 } 00700 #endif 00701 } 00702 break; 00703 default: 00704 ast_debug(1, "Do not handle CPG with event type 0x%x\n", e->cpg.event); 00705 break; 00706 } 00707 00708 sig_ss7_unlock_private(p); 00709 break; 00710 case ISUP_EVENT_RSC: 00711 ast_verbose("Resetting CIC %d\n", e->rsc.cic); 00712 chanpos = ss7_find_cic(linkset, e->rsc.cic, e->rsc.opc); 00713 if (chanpos < 0) { 00714 ast_log(LOG_WARNING, "RSC on unconfigured CIC %d\n", e->rsc.cic); 00715 break; 00716 } 00717 p = linkset->pvts[chanpos]; 00718 sig_ss7_lock_private(p); 00719 sig_ss7_set_inservice(p, 1); 00720 sig_ss7_set_remotelyblocked(p, 0); 00721 dpc = p->dpc; 00722 isup_set_call_dpc(e->rsc.call, dpc); 00723 p->ss7call = NULL; 00724 if (p->owner) 00725 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 00726 sig_ss7_unlock_private(p); 00727 isup_rlc(ss7, e->rsc.call); 00728 break; 00729 case ISUP_EVENT_GRS: 00730 ast_debug(1, "Got Reset for CICs %d to %d: Acknowledging\n", e->grs.startcic, e->grs.endcic); 00731 chanpos = ss7_find_cic(linkset, e->grs.startcic, e->grs.opc); 00732 if (chanpos < 0) { 00733 ast_log(LOG_WARNING, "GRS on unconfigured CIC %d\n", e->grs.startcic); 00734 break; 00735 } 00736 p = linkset->pvts[chanpos]; 00737 isup_gra(ss7, e->grs.startcic, e->grs.endcic, e->grs.opc); 00738 ss7_block_cics(linkset, e->grs.startcic, e->grs.endcic, e->grs.opc, NULL, 0); 00739 ss7_hangup_cics(linkset, e->grs.startcic, e->grs.endcic, e->grs.opc); 00740 break; 00741 case ISUP_EVENT_CQM: 00742 ast_debug(1, "Got Circuit group query message from CICs %d to %d\n", e->cqm.startcic, e->cqm.endcic); 00743 ss7_handle_cqm(linkset, e->cqm.startcic, e->cqm.endcic, e->cqm.opc); 00744 break; 00745 case ISUP_EVENT_GRA: 00746 ast_verbose("Got reset acknowledgement from CIC %d to %d.\n", e->gra.startcic, e->gra.endcic); 00747 ss7_inservice(linkset, e->gra.startcic, e->gra.endcic, e->gra.opc); 00748 ss7_block_cics(linkset, e->gra.startcic, e->gra.endcic, e->gra.opc, e->gra.status, 1); 00749 break; 00750 case ISUP_EVENT_IAM: 00751 ast_debug(1, "Got IAM for CIC %d and called number %s, calling number %s\n", e->iam.cic, e->iam.called_party_num, e->iam.calling_party_num); 00752 chanpos = ss7_find_cic(linkset, e->iam.cic, e->iam.opc); 00753 if (chanpos < 0) { 00754 ast_log(LOG_WARNING, "IAM on unconfigured CIC %d\n", e->iam.cic); 00755 isup_rel(ss7, e->iam.call, -1); 00756 break; 00757 } 00758 p = linkset->pvts[chanpos]; 00759 sig_ss7_lock_private(p); 00760 if (p->owner) { 00761 if (p->ss7call == e->iam.call) { 00762 sig_ss7_unlock_private(p); 00763 ast_log(LOG_WARNING, "Duplicate IAM requested on CIC %d\n", e->iam.cic); 00764 break; 00765 } else { 00766 sig_ss7_unlock_private(p); 00767 ast_log(LOG_WARNING, "Ring requested on CIC %d already in use!\n", e->iam.cic); 00768 break; 00769 } 00770 } 00771 00772 dpc = p->dpc; 00773 p->ss7call = e->iam.call; 00774 isup_set_call_dpc(p->ss7call, dpc); 00775 00776 if ((p->use_callerid) && (!ast_strlen_zero(e->iam.calling_party_num))) { 00777 ss7_apply_plan_to_number(p->cid_num, sizeof(p->cid_num), linkset, e->iam.calling_party_num, e->iam.calling_nai); 00778 p->callingpres = ss7_pres_scr2cid_pres(e->iam.presentation_ind, e->iam.screening_ind); 00779 } else 00780 p->cid_num[0] = 0; 00781 00782 /* Set DNID */ 00783 if (!ast_strlen_zero(e->iam.called_party_num)) { 00784 ss7_apply_plan_to_number(p->exten, sizeof(p->exten), linkset, 00785 e->iam.called_party_num, e->iam.called_nai); 00786 sig_ss7_set_dnid(p, p->exten); 00787 } 00788 00789 if (p->immediate) { 00790 p->exten[0] = 's'; 00791 p->exten[1] = '\0'; 00792 } else if (!ast_strlen_zero(e->iam.called_party_num)) { 00793 char *st; 00794 ss7_apply_plan_to_number(p->exten, sizeof(p->exten), linkset, e->iam.called_party_num, e->iam.called_nai); 00795 st = strchr(p->exten, '#'); 00796 if (st) { 00797 *st = '\0'; 00798 } 00799 } else { 00800 p->exten[0] = '\0'; 00801 } 00802 00803 p->cid_ani[0] = '\0'; 00804 if ((p->use_callerid) && (!ast_strlen_zero(e->iam.generic_name))) 00805 ast_copy_string(p->cid_name, e->iam.generic_name, sizeof(p->cid_name)); 00806 else 00807 p->cid_name[0] = '\0'; 00808 00809 p->cid_ani2 = e->iam.oli_ani2; 00810 p->cid_ton = 0; 00811 ast_copy_string(p->charge_number, e->iam.charge_number, sizeof(p->charge_number)); 00812 ast_copy_string(p->gen_add_number, e->iam.gen_add_number, sizeof(p->gen_add_number)); 00813 p->gen_add_type = e->iam.gen_add_type; 00814 p->gen_add_nai = e->iam.gen_add_nai; 00815 p->gen_add_pres_ind = e->iam.gen_add_pres_ind; 00816 p->gen_add_num_plan = e->iam.gen_add_num_plan; 00817 ast_copy_string(p->gen_dig_number, e->iam.gen_dig_number, sizeof(p->gen_dig_number)); 00818 p->gen_dig_type = e->iam.gen_dig_type; 00819 p->gen_dig_scheme = e->iam.gen_dig_scheme; 00820 ast_copy_string(p->jip_number, e->iam.jip_number, sizeof(p->jip_number)); 00821 ast_copy_string(p->orig_called_num, e->iam.orig_called_num, sizeof(p->orig_called_num)); 00822 ast_copy_string(p->redirecting_num, e->iam.redirecting_num, sizeof(p->redirecting_num)); 00823 ast_copy_string(p->generic_name, e->iam.generic_name, sizeof(p->generic_name)); 00824 p->calling_party_cat = e->iam.calling_party_cat; 00825 00826 sig_ss7_set_caller_id(p); 00827 00828 if (ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num)) { 00829 if (e->iam.cot_check_required) { 00830 sig_ss7_loopback(p, 1); 00831 } else 00832 ss7_start_call(p, linkset); 00833 } else { 00834 ast_debug(1, "Call on CIC for unconfigured extension %s\n", p->exten); 00835 p->alreadyhungup = 1; 00836 isup_rel(ss7, e->iam.call, AST_CAUSE_UNALLOCATED); 00837 } 00838 sig_ss7_unlock_private(p); 00839 break; 00840 case ISUP_EVENT_COT: 00841 chanpos = ss7_find_cic(linkset, e->cot.cic, e->cot.opc); 00842 if (chanpos < 0) { 00843 ast_log(LOG_WARNING, "COT on unconfigured CIC %d\n", e->cot.cic); 00844 isup_rel(ss7, e->cot.call, -1); 00845 break; 00846 } 00847 p = linkset->pvts[chanpos]; 00848 00849 sig_ss7_lock_private(p); 00850 if (p->loopedback) { 00851 sig_ss7_loopback(p, 0); 00852 ss7_start_call(p, linkset); 00853 } 00854 sig_ss7_unlock_private(p); 00855 break; 00856 case ISUP_EVENT_CCR: 00857 ast_debug(1, "Got CCR request on CIC %d\n", e->ccr.cic); 00858 chanpos = ss7_find_cic(linkset, e->ccr.cic, e->ccr.opc); 00859 if (chanpos < 0) { 00860 ast_log(LOG_WARNING, "CCR on unconfigured CIC %d\n", e->ccr.cic); 00861 break; 00862 } 00863 00864 p = linkset->pvts[chanpos]; 00865 00866 sig_ss7_lock_private(p); 00867 sig_ss7_loopback(p, 1); 00868 sig_ss7_unlock_private(p); 00869 00870 isup_lpa(linkset->ss7, e->ccr.cic, p->dpc); 00871 break; 00872 case ISUP_EVENT_CVT: 00873 ast_debug(1, "Got CVT request on CIC %d\n", e->cvt.cic); 00874 chanpos = ss7_find_cic(linkset, e->cvt.cic, e->cvt.opc); 00875 if (chanpos < 0) { 00876 ast_log(LOG_WARNING, "CVT on unconfigured CIC %d\n", e->cvt.cic); 00877 break; 00878 } 00879 00880 p = linkset->pvts[chanpos]; 00881 00882 sig_ss7_lock_private(p); 00883 sig_ss7_loopback(p, 1); 00884 sig_ss7_unlock_private(p); 00885 00886 isup_cvr(linkset->ss7, e->cvt.cic, p->dpc); 00887 break; 00888 case ISUP_EVENT_REL: 00889 chanpos = ss7_find_cic(linkset, e->rel.cic, e->rel.opc); 00890 if (chanpos < 0) { 00891 ast_log(LOG_WARNING, "REL on unconfigured CIC %d\n", e->rel.cic); 00892 break; 00893 } 00894 p = linkset->pvts[chanpos]; 00895 sig_ss7_lock_private(p); 00896 if (p->owner) { 00897 p->owner->hangupcause = e->rel.cause; 00898 p->owner->_softhangup |= AST_SOFTHANGUP_DEV; 00899 } else { 00900 ast_log(LOG_WARNING, "REL on channel (CIC %d) without owner!\n", p->cic); 00901 } 00902 00903 /* End the loopback if we have one */ 00904 sig_ss7_loopback(p, 0); 00905 00906 isup_rlc(ss7, e->rel.call); 00907 p->ss7call = NULL; 00908 00909 sig_ss7_unlock_private(p); 00910 break; 00911 case ISUP_EVENT_ACM: 00912 chanpos = ss7_find_cic(linkset, e->acm.cic, e->acm.opc); 00913 if (chanpos < 0) { 00914 ast_log(LOG_WARNING, "ACM on unconfigured CIC %d\n", e->acm.cic); 00915 isup_rel(ss7, e->acm.call, -1); 00916 break; 00917 } else { 00918 p = linkset->pvts[chanpos]; 00919 00920 ast_debug(1, "Queueing frame from SS7_EVENT_ACM on CIC %d\n", p->cic); 00921 00922 if (e->acm.call_ref_ident > 0) { 00923 p->rlt = 1; /* Setting it but not using it here*/ 00924 } 00925 00926 sig_ss7_lock_private(p); 00927 sig_ss7_queue_control(linkset, chanpos, AST_CONTROL_PROCEEDING); 00928 p->proceeding = 1; 00929 sig_ss7_set_dialing(p, 0); 00930 /* Send alerting if subscriber is free */ 00931 if (e->acm.called_party_status_ind == 1) { 00932 p->alerting = 1; 00933 sig_ss7_queue_control(linkset, chanpos, AST_CONTROL_RINGING); 00934 } 00935 sig_ss7_unlock_private(p); 00936 } 00937 break; 00938 case ISUP_EVENT_CGB: 00939 chanpos = ss7_find_cic(linkset, e->cgb.startcic, e->cgb.opc); 00940 if (chanpos < 0) { 00941 ast_log(LOG_WARNING, "CGB on unconfigured CIC %d\n", e->cgb.startcic); 00942 break; 00943 } 00944 p = linkset->pvts[chanpos]; 00945 ss7_block_cics(linkset, e->cgb.startcic, e->cgb.endcic, e->cgb.opc, e->cgb.status, 1); 00946 isup_cgba(linkset->ss7, e->cgb.startcic, e->cgb.endcic, e->cgb.opc, e->cgb.status, e->cgb.type); 00947 break; 00948 case ISUP_EVENT_CGU: 00949 chanpos = ss7_find_cic(linkset, e->cgu.startcic, e->cgu.opc); 00950 if (chanpos < 0) { 00951 ast_log(LOG_WARNING, "CGU on unconfigured CIC %d\n", e->cgu.startcic); 00952 break; 00953 } 00954 p = linkset->pvts[chanpos]; 00955 ss7_block_cics(linkset, e->cgu.startcic, e->cgu.endcic, e->cgu.opc, e->cgu.status, 0); 00956 isup_cgua(linkset->ss7, e->cgu.startcic, e->cgu.endcic, e->cgu.opc, e->cgu.status, e->cgu.type); 00957 break; 00958 case ISUP_EVENT_UCIC: 00959 chanpos = ss7_find_cic(linkset, e->ucic.cic, e->ucic.opc); 00960 if (chanpos < 0) { 00961 ast_log(LOG_WARNING, "UCIC on unconfigured CIC %d\n", e->ucic.cic); 00962 break; 00963 } 00964 p = linkset->pvts[chanpos]; 00965 ast_debug(1, "Unequiped Circuit Id Code on CIC %d\n", e->ucic.cic); 00966 sig_ss7_lock_private(p); 00967 sig_ss7_set_remotelyblocked(p, 1); 00968 sig_ss7_set_inservice(p, 0); 00969 sig_ss7_unlock_private(p);/* doesn't require a SS7 acknowledgement */ 00970 break; 00971 case ISUP_EVENT_BLO: 00972 chanpos = ss7_find_cic(linkset, e->blo.cic, e->blo.opc); 00973 if (chanpos < 0) { 00974 ast_log(LOG_WARNING, "BLO on unconfigured CIC %d\n", e->blo.cic); 00975 break; 00976 } 00977 p = linkset->pvts[chanpos]; 00978 ast_debug(1, "Blocking CIC %d\n", e->blo.cic); 00979 sig_ss7_lock_private(p); 00980 sig_ss7_set_remotelyblocked(p, 1); 00981 sig_ss7_unlock_private(p); 00982 isup_bla(linkset->ss7, e->blo.cic, p->dpc); 00983 break; 00984 case ISUP_EVENT_BLA: 00985 chanpos = ss7_find_cic(linkset, e->bla.cic, e->bla.opc); 00986 if (chanpos < 0) { 00987 ast_log(LOG_WARNING, "BLA on unconfigured CIC %d\n", e->bla.cic); 00988 break; 00989 } 00990 ast_debug(1, "Blocking CIC %d\n", e->bla.cic); 00991 p = linkset->pvts[chanpos]; 00992 sig_ss7_lock_private(p); 00993 sig_ss7_set_locallyblocked(p, 1); 00994 sig_ss7_unlock_private(p); 00995 break; 00996 case ISUP_EVENT_UBL: 00997 chanpos = ss7_find_cic(linkset, e->ubl.cic, e->ubl.opc); 00998 if (chanpos < 0) { 00999 ast_log(LOG_WARNING, "UBL on unconfigured CIC %d\n", e->ubl.cic); 01000 break; 01001 } 01002 p = linkset->pvts[chanpos]; 01003 ast_debug(1, "Unblocking CIC %d\n", e->ubl.cic); 01004 sig_ss7_lock_private(p); 01005 sig_ss7_set_remotelyblocked(p, 0); 01006 sig_ss7_unlock_private(p); 01007 isup_uba(linkset->ss7, e->ubl.cic, p->dpc); 01008 break; 01009 case ISUP_EVENT_UBA: 01010 chanpos = ss7_find_cic(linkset, e->uba.cic, e->uba.opc); 01011 if (chanpos < 0) { 01012 ast_log(LOG_WARNING, "UBA on unconfigured CIC %d\n", e->uba.cic); 01013 break; 01014 } 01015 p = linkset->pvts[chanpos]; 01016 ast_debug(1, "Unblocking CIC %d\n", e->uba.cic); 01017 sig_ss7_lock_private(p); 01018 sig_ss7_set_locallyblocked(p, 0); 01019 sig_ss7_unlock_private(p); 01020 break; 01021 case ISUP_EVENT_CON: 01022 case ISUP_EVENT_ANM: 01023 if (e->e == ISUP_EVENT_CON) 01024 cic = e->con.cic; 01025 else 01026 cic = e->anm.cic; 01027 01028 chanpos = ss7_find_cic(linkset, cic, (e->e == ISUP_EVENT_ANM) ? e->anm.opc : e->con.opc); 01029 if (chanpos < 0) { 01030 ast_log(LOG_WARNING, "ANM/CON on unconfigured CIC %d\n", cic); 01031 isup_rel(ss7, (e->e == ISUP_EVENT_ANM) ? e->anm.call : e->con.call, -1); 01032 break; 01033 } else { 01034 p = linkset->pvts[chanpos]; 01035 sig_ss7_lock_private(p); 01036 sig_ss7_queue_control(linkset, chanpos, AST_CONTROL_ANSWER); 01037 #if 0 /* This code no longer seems to be necessary so I did not convert it. */ 01038 if (p->dsp && p->dsp_features) { 01039 ast_dsp_set_features(p->dsp, p->dsp_features); 01040 p->dsp_features = 0; 01041 } 01042 #endif 01043 sig_ss7_set_echocanceller(p, 1); 01044 sig_ss7_unlock_private(p); 01045 } 01046 break; 01047 case ISUP_EVENT_RLC: 01048 chanpos = ss7_find_cic(linkset, e->rlc.cic, e->rlc.opc); 01049 if (chanpos < 0) { 01050 ast_log(LOG_WARNING, "RLC on unconfigured CIC %d\n", e->rlc.cic); 01051 break; 01052 } else { 01053 p = linkset->pvts[chanpos]; 01054 sig_ss7_lock_private(p); 01055 if (p->alreadyhungup) 01056 p->ss7call = NULL; 01057 else 01058 ast_log(LOG_NOTICE, "Received RLC out and we haven't sent REL. Ignoring.\n"); 01059 sig_ss7_unlock_private(p); 01060 } 01061 break; 01062 case ISUP_EVENT_FAA: 01063 chanpos = ss7_find_cic(linkset, e->faa.cic, e->faa.opc); 01064 if (chanpos < 0) { 01065 ast_log(LOG_WARNING, "FAA on unconfigured CIC %d\n", e->faa.cic); 01066 break; 01067 } else { 01068 p = linkset->pvts[chanpos]; 01069 ast_debug(1, "FAA received on CIC %d\n", e->faa.cic); 01070 sig_ss7_lock_private(p); 01071 if (p->alreadyhungup){ 01072 p->ss7call = NULL; 01073 ast_log(LOG_NOTICE, "Received FAA and we haven't sent FAR. Ignoring.\n"); 01074 } 01075 sig_ss7_unlock_private(p); 01076 } 01077 break; 01078 default: 01079 ast_debug(1, "Unknown event %s\n", ss7_event2str(e->e)); 01080 break; 01081 } 01082 } 01083 ast_mutex_unlock(&linkset->lock); 01084 } 01085 01086 return 0; 01087 }
static int ss7_pres_scr2cid_pres | ( | char | presentation_ind, | |
char | screening_ind | |||
) | [static] |
static void ss7_rel | ( | struct sig_ss7_linkset * | ss7 | ) | [inline, static] |
Definition at line 1089 of file sig_ss7.c.
References ast_mutex_unlock, and sig_ss7_linkset::lock.
Referenced by sig_ss7_answer(), sig_ss7_call(), sig_ss7_hangup(), and sig_ss7_indicate().
01090 { 01091 ast_mutex_unlock(&ss7->lock); 01092 }
static void ss7_reset_linkset | ( | struct sig_ss7_linkset * | linkset | ) | [static] |
Definition at line 397 of file sig_ss7.c.
References ast_verbose, sig_ss7_chan::cic, sig_ss7_chan::dpc, sig_ss7_linkset::numchans, sig_ss7_linkset::pvts, and sig_ss7_linkset::ss7.
00398 { 00399 int i, startcic = -1, endcic, dpc; 00400 00401 if (linkset->numchans <= 0) 00402 return; 00403 00404 startcic = linkset->pvts[0]->cic; 00405 /* DB: CIC's DPC fix */ 00406 dpc = linkset->pvts[0]->dpc; 00407 00408 for (i = 0; i < linkset->numchans; i++) { 00409 if (linkset->pvts[i+1] && linkset->pvts[i+1]->dpc == dpc && ((linkset->pvts[i+1]->cic - linkset->pvts[i]->cic) == 1) && (linkset->pvts[i]->cic - startcic < 31)) { 00410 continue; 00411 } else { 00412 endcic = linkset->pvts[i]->cic; 00413 ast_verbose("Resetting CICs %d to %d\n", startcic, endcic); 00414 isup_grs(linkset->ss7, startcic, endcic, dpc); 00415 00416 /* DB: CIC's DPC fix */ 00417 if (linkset->pvts[i+1]) { 00418 startcic = linkset->pvts[i+1]->cic; 00419 dpc = linkset->pvts[i+1]->dpc; 00420 } 00421 } 00422 } 00423 }
static void ss7_start_call | ( | struct sig_ss7_chan * | p, | |
struct sig_ss7_linkset * | linkset | |||
) | [static] |
Definition at line 426 of file sig_ss7.c.
References sig_ss7_chan::alreadyhungup, ast_hangup(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_pbx_start(), AST_STATE_RING, ast_strlen_zero(), ast_verb, sig_ss7_chan::call_ref_ident, sig_ss7_chan::call_ref_pc, sig_ss7_chan::calling_party_cat, sig_ss7_chan::charge_number, sig_ss7_chan::cic, sig_ss7_chan::exten, sig_ss7_linkset::flags, sig_ss7_chan::gen_add_number, sig_ss7_chan::gen_dig_number, sig_ss7_chan::gen_dig_scheme, sig_ss7_chan::gen_dig_type, sig_ss7_chan::generic_name, sig_ss7_chan::jip_number, LINKSET_FLAG_EXPLICITACM, sig_ss7_linkset::lock, LOG_WARNING, sig_ss7_chan::lspi_ident, ast_channel::name, sig_ss7_chan::orig_called_num, pbx_builtin_setvar_helper(), sig_ss7_chan::proceeding, sig_ss7_chan::redirecting_num, SIG_SS7_ALAW, sig_ss7_new_ast_channel(), sig_ss7_set_echocanceller(), SIG_SS7_ULAW, sig_ss7_linkset::ss7, sig_ss7_chan::ss7call, and sig_ss7_linkset::type.
00427 { 00428 struct ss7 *ss7 = linkset->ss7; 00429 int law; 00430 struct ast_channel *c; 00431 char tmp[256]; 00432 00433 if (!(linkset->flags & LINKSET_FLAG_EXPLICITACM)) { 00434 p->proceeding = 1; 00435 isup_acm(ss7, p->ss7call); 00436 } 00437 00438 if (linkset->type == SS7_ITU) { 00439 law = SIG_SS7_ALAW; 00440 } else { 00441 law = SIG_SS7_ULAW; 00442 } 00443 00444 /* 00445 * Release the SS7 lock while we create the channel 00446 * so other threads can send messages. 00447 */ 00448 ast_mutex_unlock(&linkset->lock); 00449 c = sig_ss7_new_ast_channel(p, AST_STATE_RING, law, 0, p->exten, NULL); 00450 if (!c) { 00451 ast_log(LOG_WARNING, "Unable to start PBX on CIC %d\n", p->cic); 00452 ast_mutex_lock(&linkset->lock); 00453 isup_rel(linkset->ss7, p->ss7call, -1); 00454 p->proceeding = 0; 00455 p->alreadyhungup = 1; 00456 return; 00457 } 00458 00459 sig_ss7_set_echocanceller(p, 1); 00460 00461 /* 00462 * It is reasonably safe to set the following 00463 * channel variables while the channel private 00464 * structure is locked. The PBX has not been 00465 * started yet and it is unlikely that any other task 00466 * will do anything with the channel we have just 00467 * created. 00468 * 00469 * We only reference these variables in the context of the ss7_linkset function 00470 * when receiving either and IAM or a COT message. 00471 */ 00472 if (!ast_strlen_zero(p->charge_number)) { 00473 pbx_builtin_setvar_helper(c, "SS7_CHARGE_NUMBER", p->charge_number); 00474 /* Clear this after we set it */ 00475 p->charge_number[0] = 0; 00476 } 00477 if (!ast_strlen_zero(p->gen_add_number)) { 00478 pbx_builtin_setvar_helper(c, "SS7_GENERIC_ADDRESS", p->gen_add_number); 00479 /* Clear this after we set it */ 00480 p->gen_add_number[0] = 0; 00481 } 00482 if (!ast_strlen_zero(p->jip_number)) { 00483 pbx_builtin_setvar_helper(c, "SS7_JIP", p->jip_number); 00484 /* Clear this after we set it */ 00485 p->jip_number[0] = 0; 00486 } 00487 if (!ast_strlen_zero(p->gen_dig_number)) { 00488 pbx_builtin_setvar_helper(c, "SS7_GENERIC_DIGITS", p->gen_dig_number); 00489 /* Clear this after we set it */ 00490 p->gen_dig_number[0] = 0; 00491 } 00492 if (!ast_strlen_zero(p->orig_called_num)) { 00493 pbx_builtin_setvar_helper(c, "SS7_ORIG_CALLED_NUM", p->orig_called_num); 00494 /* Clear this after we set it */ 00495 p->orig_called_num[0] = 0; 00496 } 00497 00498 snprintf(tmp, sizeof(tmp), "%d", p->gen_dig_type); 00499 pbx_builtin_setvar_helper(c, "SS7_GENERIC_DIGTYPE", tmp); 00500 /* Clear this after we set it */ 00501 p->gen_dig_type = 0; 00502 00503 snprintf(tmp, sizeof(tmp), "%d", p->gen_dig_scheme); 00504 pbx_builtin_setvar_helper(c, "SS7_GENERIC_DIGSCHEME", tmp); 00505 /* Clear this after we set it */ 00506 p->gen_dig_scheme = 0; 00507 00508 if (!ast_strlen_zero(p->lspi_ident)) { 00509 pbx_builtin_setvar_helper(c, "SS7_LSPI_IDENT", p->lspi_ident); 00510 /* Clear this after we set it */ 00511 p->lspi_ident[0] = 0; 00512 } 00513 00514 snprintf(tmp, sizeof(tmp), "%d", p->call_ref_ident); 00515 pbx_builtin_setvar_helper(c, "SS7_CALLREF_IDENT", tmp); 00516 /* Clear this after we set it */ 00517 p->call_ref_ident = 0; 00518 00519 snprintf(tmp, sizeof(tmp), "%d", p->call_ref_pc); 00520 pbx_builtin_setvar_helper(c, "SS7_CALLREF_PC", tmp); 00521 /* Clear this after we set it */ 00522 p->call_ref_pc = 0; 00523 00524 snprintf(tmp, sizeof(tmp), "%d", p->calling_party_cat); 00525 pbx_builtin_setvar_helper(c, "SS7_CALLING_PARTY_CATEGORY", tmp); 00526 /* Clear this after we set it */ 00527 p->calling_party_cat = 0; 00528 00529 if (!ast_strlen_zero(p->redirecting_num)) { 00530 pbx_builtin_setvar_helper(c, "SS7_REDIRECTING_NUMBER", p->redirecting_num); 00531 /* Clear this after we set it */ 00532 p->redirecting_num[0] = 0; 00533 } 00534 if (!ast_strlen_zero(p->generic_name)) { 00535 pbx_builtin_setvar_helper(c, "SS7_GENERIC_NAME", p->generic_name); 00536 /* Clear this after we set it */ 00537 p->generic_name[0] = 0; 00538 } 00539 00540 if (ast_pbx_start(c)) { 00541 ast_log(LOG_WARNING, "Unable to start PBX on %s (CIC %d)\n", c->name, p->cic); 00542 ast_hangup(c); 00543 } else { 00544 ast_verb(3, "Accepting call to '%s' on CIC %d\n", p->exten, p->cic); 00545 } 00546 ast_mutex_lock(&linkset->lock); 00547 }