86 #include <sys/socket.h> 88 #include <arpa/inet.h> 90 #include <sys/ioctl.h> 93 #include <semaphore.h> 164 #if defined(AST_MISDN_ENHANCEMENTS) 169 #define MISDN_CC_RECORD_AGE_MAX (6UL * 60 * 60) 171 #define MISDN_CC_REQUEST_WAIT_MAX 5 183 struct misdn_cc_caller {
188 struct misdn_cc_notify {
200 struct misdn_cc_record {
233 int requested_retention;
238 int retention_enabled;
261 int outstanding_message;
264 int activation_requested;
274 enum FacErrorCode error_code;
277 enum FacRejectCode reject_code;
291 struct Q931_Bc_Hlc_Llc setup_bc_hlc_llc;
301 struct misdn_cc_notify remote_user_free;
304 struct misdn_cc_notify b_free;
310 static __u16 misdn_cc_record_id;
312 static __s16 misdn_invoke_id;
314 static const char misdn_no_response_from_network[] =
"No response from network";
315 static const char misdn_cc_record_not_found[] =
"Call completion record not found";
318 #define MISDN_CC_RECORD_ID "MISDN_CC_RECORD_ID" 319 #define MISDN_CC_STATUS "MISDN_CC_STATUS" 320 #define MISDN_ERROR_MSG "MISDN_ERROR_MSG" 371 #define chan_list_ref(obj, debug) ao2_t_ref((obj), +1, (debug)) 372 #define chan_list_unref(obj, debug) ao2_t_ref((obj), -1, (debug)) 449 char ast_rd_buf[4096];
473 struct timeval faxdetect_tv;
522 #if defined(AST_MISDN_ENHANCEMENTS) 526 struct misdn_cc_caller *peer;
603 struct timeval overlap_tv;
634 for (r = robin, robin =
NULL; r; r =
next) {
645 for (; iter; iter = iter->
next) {
646 if (!strcasecmp(iter->
group, group)) {
676 __attribute__((
format(printf, 3, 4)));
683 #define MISDN_ASTERISK_TECH_PVT(ast) ast_channel_tech_pvt(ast) 684 #define MISDN_ASTERISK_TECH_PVT_SET(ast, value) ast_channel_tech_pvt_set(ast, value) 723 #if defined(AST_MISDN_ENHANCEMENTS) 724 static const char misdn_command_name[] =
"misdn_command";
725 static int misdn_command_exec(
struct ast_channel *chan,
const char *data);
754 for (list = cl_te; list; list = list->
next) {
765 #if defined(mISDN_NATIVE_BRIDGING) 772 for (tmp = cl_te;
tmp; tmp = tmp->
next) {
773 if (tmp->
ast == ast) {
791 for (tmp = cl_te;
tmp; tmp = tmp->
next) {
803 #if defined(AST_MISDN_ENHANCEMENTS) 827 static void misdn_cc_ds_destroy(
void *data)
829 struct misdn_cc_caller *cc_caller = data;
832 cc_caller->chan =
NULL;
839 #if defined(AST_MISDN_ENHANCEMENTS) 851 static void *misdn_cc_ds_duplicate(
void *data)
853 struct misdn_cc_caller *cc_caller = data;
861 #if defined(AST_MISDN_ENHANCEMENTS) 864 .destroy = misdn_cc_ds_destroy,
865 .duplicate = misdn_cc_ds_duplicate,
869 #if defined(AST_MISDN_ENHANCEMENTS) 883 static void misdn_cc_set_peer_var(
struct misdn_cc_caller *peer,
const char *
var,
904 #if defined(AST_MISDN_ENHANCEMENTS) 909 static struct misdn_cc_caller *misdn_cc_caller_get(
struct ast_channel *chan)
912 struct misdn_cc_caller *cc_caller;
922 cc_caller = datastore->
data;
930 #if defined(AST_MISDN_ENHANCEMENTS) 942 static struct misdn_cc_record *misdn_cc_find_by_id(
long record_id)
944 struct misdn_cc_record *current;
947 if (current->record_id == record_id) {
957 #if defined(AST_MISDN_ENHANCEMENTS) 970 static struct misdn_cc_record *misdn_cc_find_by_linkage(
int port,
int linkage_id)
972 struct misdn_cc_record *current;
975 if (current->port == port
977 && current->mode.ptmp.linkage_id == linkage_id) {
987 #if defined(AST_MISDN_ENHANCEMENTS) 1000 static struct misdn_cc_record *misdn_cc_find_by_invoke(
int port,
int invoke_id)
1002 struct misdn_cc_record *current;
1005 if (current->outstanding_message
1006 && current->invoke_id == invoke_id
1007 && current->port == port) {
1017 #if defined(AST_MISDN_ENHANCEMENTS) 1030 static struct misdn_cc_record *misdn_cc_find_by_reference(
int port,
int reference_id)
1032 struct misdn_cc_record *current;
1035 if (current->activated
1036 && current->port == port
1038 && current->mode.ptmp.reference_id == reference_id) {
1048 #if defined(AST_MISDN_ENHANCEMENTS) 1060 static struct misdn_cc_record *misdn_cc_find_by_bc(
const struct misdn_bchannel *
bc)
1062 struct misdn_cc_record *current;
1067 && current->mode.ptp.bc == bc) {
1080 #if defined(AST_MISDN_ENHANCEMENTS) 1091 static void misdn_cc_delete(
struct misdn_cc_record *doomed)
1093 struct misdn_cc_record *current;
1096 if (current == doomed) {
1108 #if defined(AST_MISDN_ENHANCEMENTS) 1117 static void misdn_cc_remove_old(
void)
1119 struct misdn_cc_record *current;
1124 if (MISDN_CC_RECORD_AGE_MAX < now - current->time_created) {
1125 if (current->ptp && current->mode.ptp.bc) {
1127 current->mode.ptp.bc->fac_out.Function = Fac_None;
1141 #if defined(AST_MISDN_ENHANCEMENTS) 1151 static long misdn_cc_record_id_new(
void)
1156 record_id = ++misdn_cc_record_id;
1157 first_id = record_id;
1158 while (misdn_cc_find_by_id(record_id)) {
1159 record_id = ++misdn_cc_record_id;
1160 if (record_id == first_id) {
1165 chan_misdn_log(0, 0,
" --> ERROR Too many call completion records!\n");
1175 #if defined(AST_MISDN_ENHANCEMENTS) 1185 static struct misdn_cc_record *misdn_cc_new(
void)
1187 struct misdn_cc_record *cc_record;
1190 misdn_cc_remove_old();
1192 cc_record =
ast_calloc(1,
sizeof(*cc_record));
1194 record_id = misdn_cc_record_id_new();
1195 if (record_id < 0) {
1201 cc_record->record_id = record_id;
1202 cc_record->port = -1;
1203 cc_record->invoke_id = ++misdn_invoke_id;
1204 cc_record->party_a_free = 1;
1205 cc_record->error_code = FacError_None;
1206 cc_record->reject_code = FacReject_None;
1207 cc_record->time_created = time(
NULL);
1216 #if defined(AST_MISDN_ENHANCEMENTS) 1223 static void misdn_cc_destroy(
void)
1225 struct misdn_cc_record *current;
1234 #if defined(AST_MISDN_ENHANCEMENTS) 1241 static void misdn_cc_init(
void)
1243 misdn_cc_record_id = 0;
1247 #if defined(AST_MISDN_ENHANCEMENTS) 1257 static int misdn_cc_response_check(
void *data)
1260 struct misdn_cc_record *cc_record;
1263 cc_record = misdn_cc_find_by_id(*(
long *) data);
1265 if (cc_record->outstanding_message) {
1276 return not_responded;
1280 #if defined(AST_MISDN_ENHANCEMENTS) 1292 static void misdn_cc_response_wait(
struct ast_channel *chan,
int wait_seconds,
long record_id)
1296 for (count = 2 * MISDN_CC_REQUEST_WAIT_MAX; count--;) {
1306 #if defined(AST_MISDN_ENHANCEMENTS) 1315 static const char *misdn_to_str_reject_code(
enum FacRejectCode code)
1317 static const struct {
1318 enum FacRejectCode code;
1322 { FacReject_None,
"No reject occurred" },
1323 { FacReject_Unknown,
"Unknown reject code" },
1325 { FacReject_Gen_UnrecognizedComponent,
"General: Unrecognized Component" },
1326 { FacReject_Gen_MistypedComponent,
"General: Mistyped Component" },
1327 { FacReject_Gen_BadlyStructuredComponent,
"General: Badly Structured Component" },
1329 { FacReject_Inv_DuplicateInvocation,
"Invoke: Duplicate Invocation" },
1330 { FacReject_Inv_UnrecognizedOperation,
"Invoke: Unrecognized Operation" },
1331 { FacReject_Inv_MistypedArgument,
"Invoke: Mistyped Argument" },
1332 { FacReject_Inv_ResourceLimitation,
"Invoke: Resource Limitation" },
1333 { FacReject_Inv_InitiatorReleasing,
"Invoke: Initiator Releasing" },
1334 { FacReject_Inv_UnrecognizedLinkedID,
"Invoke: Unrecognized Linked ID" },
1335 { FacReject_Inv_LinkedResponseUnexpected,
"Invoke: Linked Response Unexpected" },
1336 { FacReject_Inv_UnexpectedChildOperation,
"Invoke: Unexpected Child Operation" },
1338 { FacReject_Res_UnrecognizedInvocation,
"Result: Unrecognized Invocation" },
1339 { FacReject_Res_ResultResponseUnexpected,
"Result: Result Response Unexpected" },
1340 { FacReject_Res_MistypedResult,
"Result: Mistyped Result" },
1342 { FacReject_Err_UnrecognizedInvocation,
"Error: Unrecognized Invocation" },
1343 { FacReject_Err_ErrorResponseUnexpected,
"Error: Error Response Unexpected" },
1344 { FacReject_Err_UnrecognizedError,
"Error: Unrecognized Error" },
1345 { FacReject_Err_UnexpectedError,
"Error: Unexpected Error" },
1346 { FacReject_Err_MistypedParameter,
"Error: Mistyped Parameter" },
1352 for (index = 0; index <
ARRAY_LEN(arr); ++index) {
1353 if (arr[index].code == code) {
1354 return arr[index].name;
1362 #if defined(AST_MISDN_ENHANCEMENTS) 1371 static const char *misdn_to_str_error_code(
enum FacErrorCode code)
1373 static const struct {
1374 enum FacErrorCode code;
1378 { FacError_None,
"No error occurred" },
1379 { FacError_Unknown,
"Unknown OID error code" },
1381 { FacError_Gen_NotSubscribed,
"General: Not Subscribed" },
1382 { FacError_Gen_NotAvailable,
"General: Not Available" },
1383 { FacError_Gen_NotImplemented,
"General: Not Implemented" },
1384 { FacError_Gen_InvalidServedUserNr,
"General: Invalid Served User Number" },
1385 { FacError_Gen_InvalidCallState,
"General: Invalid Call State" },
1386 { FacError_Gen_BasicServiceNotProvided,
"General: Basic Service Not Provided" },
1387 { FacError_Gen_NotIncomingCall,
"General: Not Incoming Call" },
1388 { FacError_Gen_SupplementaryServiceInteractionNotAllowed,
"General: Supplementary Service Interaction Not Allowed" },
1389 { FacError_Gen_ResourceUnavailable,
"General: Resource Unavailable" },
1391 { FacError_Div_InvalidDivertedToNr,
"Diversion: Invalid Diverted To Number" },
1392 { FacError_Div_SpecialServiceNr,
"Diversion: Special Service Number" },
1393 { FacError_Div_DiversionToServedUserNr,
"Diversion: Diversion To Served User Number" },
1394 { FacError_Div_IncomingCallAccepted,
"Diversion: Incoming Call Accepted" },
1395 { FacError_Div_NumberOfDiversionsExceeded,
"Diversion: Number Of Diversions Exceeded" },
1396 { FacError_Div_NotActivated,
"Diversion: Not Activated" },
1397 { FacError_Div_RequestAlreadyAccepted,
"Diversion: Request Already Accepted" },
1399 { FacError_AOC_NoChargingInfoAvailable,
"AOC: No Charging Info Available" },
1401 { FacError_CCBS_InvalidCallLinkageID,
"CCBS: Invalid Call Linkage ID" },
1402 { FacError_CCBS_InvalidCCBSReference,
"CCBS: Invalid CCBS Reference" },
1403 { FacError_CCBS_LongTermDenial,
"CCBS: Long Term Denial" },
1404 { FacError_CCBS_ShortTermDenial,
"CCBS: Short Term Denial" },
1405 { FacError_CCBS_IsAlreadyActivated,
"CCBS: Is Already Activated" },
1406 { FacError_CCBS_AlreadyAccepted,
"CCBS: Already Accepted" },
1407 { FacError_CCBS_OutgoingCCBSQueueFull,
"CCBS: Outgoing CCBS Queue Full" },
1408 { FacError_CCBS_CallFailureReasonNotBusy,
"CCBS: Call Failure Reason Not Busy" },
1409 { FacError_CCBS_NotReadyForCall,
"CCBS: Not Ready For Call" },
1411 { FacError_CCBS_T_LongTermDenial,
"CCBS-T: Long Term Denial" },
1412 { FacError_CCBS_T_ShortTermDenial,
"CCBS-T: Short Term Denial" },
1414 { FacError_ECT_LinkIdNotAssignedByNetwork,
"ECT: Link ID Not Assigned By Network" },
1420 for (index = 0; index <
ARRAY_LEN(arr); ++index) {
1421 if (arr[index].code == code) {
1422 return arr[index].name;
1430 #if defined(AST_MISDN_ENHANCEMENTS) 1441 unsigned diversion_reason;
1445 diversion_reason = 1;
1448 diversion_reason = 2;
1451 diversion_reason = 3;
1454 diversion_reason = 0;
1458 return diversion_reason;
1462 #if defined(AST_MISDN_ENHANCEMENTS) 1475 switch (diversion_reason) {
1494 #if defined(AST_MISDN_ENHANCEMENTS) 1504 static unsigned misdn_to_PresentedNumberUnscreened_type(
int presentation,
int number_present)
1508 switch (presentation) {
1510 if (number_present) {
1517 if (number_present) {
1532 #if defined(AST_MISDN_ENHANCEMENTS) 1541 static int PresentedNumberUnscreened_to_misdn_pres(
unsigned type)
1561 return presentation;
1565 #if defined(AST_MISDN_ENHANCEMENTS) 1576 unsigned party_plan;
1578 switch (number_plan) {
1609 #if defined(AST_MISDN_ENHANCEMENTS) 1622 switch (party_plan) {
1648 #if defined(AST_MISDN_ENHANCEMENTS) 1692 #if defined(AST_MISDN_ENHANCEMENTS) 1701 static enum mISDN_NUMBER_TYPE PartyNumber_to_misdn_ton_public(
unsigned party_ton)
1705 switch (party_ton) {
1736 #if defined(AST_MISDN_ENHANCEMENTS) 1780 #if defined(AST_MISDN_ENHANCEMENTS) 1789 static enum mISDN_NUMBER_TYPE PartyNumber_to_misdn_ton_private(
unsigned party_ton)
1793 switch (party_ton) {
1836 switch (number_type) {
1843 str =
"International";
1851 str =
"Network Specific";
1859 str =
"Abbreviated";
1876 int ast_number_type;
1878 switch (number_type) {
1905 return ast_number_type;
1920 switch ((ast_number_type >> 4) & 0x07) {
1962 switch (number_plan) {
2002 int ast_number_plan;
2004 switch (number_plan) {
2031 return ast_number_plan;
2046 switch (ast_number_plan & 0x0F) {
2088 switch (presentation) {
2098 str =
"Unavailable";
2119 switch (presentation) {
2134 return presentation;
2162 return presentation;
2177 switch (screening) {
2183 str =
"Passed Screen";
2187 str =
"Failed Screen";
2191 str =
"Network Number";
2212 switch (screening) {
2278 static const struct misdn_reasons {
2281 } misdn_reason_table[] = {
2298 for (index = 0; index <
ARRAY_LEN(misdn_reason_table); ++index) {
2299 if (misdn_reason_table[index].ast == ast) {
2300 return misdn_reason_table[index].q931;
2377 for (index = 0; index <
ARRAY_LEN(allowed_bearers_array); ++index) {
2378 if (allowed_bearers_array[index].cap == cap) {
2379 return allowed_bearers_array[index].
display;
2383 return "Unknown Bearer";
2386 #if defined(AST_MISDN_ENHANCEMENTS) 2396 static void misdn_PartyNumber_fill(
struct FacPartyNumber *party,
const struct misdn_party_id *
id)
2399 party->LengthOfNumber = strlen((
char *) party->Number);
2400 party->Type = misdn_to_PartyNumber_plan(id->
number_plan);
2401 switch (party->Type) {
2403 party->TypeOfNumber = misdn_to_PartyNumber_ton_public(id->
number_type);
2406 party->TypeOfNumber = misdn_to_PartyNumber_ton_private(id->
number_type);
2409 party->TypeOfNumber = 0;
2415 #if defined(AST_MISDN_ENHANCEMENTS) 2425 static void misdn_PartyNumber_extract(
struct misdn_party_id *
id,
const struct FacPartyNumber *party)
2427 if (party->LengthOfNumber) {
2429 id->number_plan = PartyNumber_to_misdn_plan(party->Type);
2430 switch (party->Type) {
2432 id->number_type = PartyNumber_to_misdn_ton_public(party->TypeOfNumber);
2435 id->number_type = PartyNumber_to_misdn_ton_private(party->TypeOfNumber);
2450 #if defined(AST_MISDN_ENHANCEMENTS) 2460 static void misdn_Address_fill(
struct FacAddress *Address,
const struct misdn_party_id *
id)
2462 misdn_PartyNumber_fill(&Address->Party,
id);
2465 Address->Subaddress.Length = 0;
2469 #if defined(AST_MISDN_ENHANCEMENTS) 2479 static void misdn_PresentedNumberUnscreened_fill(
struct FacPresentedNumberUnscreened *presented,
const struct misdn_party_id *
id)
2481 presented->Type = misdn_to_PresentedNumberUnscreened_type(id->
presentation, id->
number[0] ? 1 : 0);
2482 misdn_PartyNumber_fill(&presented->Unscreened,
id);
2486 #if defined(AST_MISDN_ENHANCEMENTS) 2496 static void misdn_PresentedNumberUnscreened_extract(
struct misdn_party_id *
id,
const struct FacPresentedNumberUnscreened *presented)
2498 id->presentation = PresentedNumberUnscreened_to_misdn_pres(presented->Type);
2500 switch (presented->Type) {
2503 misdn_PartyNumber_extract(
id, &presented->Unscreened);
2517 #if defined(AST_MISDN_ENHANCEMENTS) 2518 static const char Level_Spacing[] =
" ";
2521 #if defined(AST_MISDN_ENHANCEMENTS) 2522 static void print_facility_PartyNumber(
unsigned Level,
const struct FacPartyNumber *Party,
const struct misdn_bchannel *bc)
2524 if (Party->LengthOfNumber) {
2525 const char *Spacing;
2527 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2529 Spacing, Party->Type);
2530 switch (Party->Type) {
2533 Spacing, Party->Number);
2537 Spacing, Party->TypeOfNumber, Party->Number);
2541 Spacing, Party->Number);
2545 Spacing, Party->Number);
2549 Spacing, Party->Number);
2553 Spacing, Party->TypeOfNumber, Party->Number);
2557 Spacing, Party->Number);
2566 #if defined(AST_MISDN_ENHANCEMENTS) 2567 static void print_facility_Subaddress(
unsigned Level,
const struct FacPartySubaddress *Subaddress,
const struct misdn_bchannel *bc)
2569 if (Subaddress->Length) {
2570 const char *Spacing;
2572 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2574 Spacing, Subaddress->Type);
2575 switch (Subaddress->Type) {
2577 if (Subaddress->u.UserSpecified.OddCountPresent) {
2579 Spacing, Subaddress->u.UserSpecified.OddCount, Subaddress->Length);
2582 Spacing, Subaddress->u.UserSpecified.Information);
2587 Spacing, Subaddress->u.Nsap);
2596 #if defined(AST_MISDN_ENHANCEMENTS) 2597 static void print_facility_Address(
unsigned Level,
const struct FacAddress *Address,
const struct misdn_bchannel *bc)
2599 print_facility_PartyNumber(Level, &Address->Party, bc);
2600 print_facility_Subaddress(Level, &Address->Subaddress, bc);
2604 #if defined(AST_MISDN_ENHANCEMENTS) 2605 static void print_facility_PresentedNumberUnscreened(
unsigned Level,
const struct FacPresentedNumberUnscreened *Presented,
const struct misdn_bchannel *bc)
2607 const char *Spacing;
2609 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2610 chan_misdn_log(1, bc->
port,
" -->%s Unscreened Type:%d\n", Spacing, Presented->Type);
2611 switch (Presented->Type) {
2614 print_facility_PartyNumber(Level + 2, &Presented->Unscreened, bc);
2624 print_facility_PartyNumber(Level + 2, &Presented->Unscreened, bc);
2632 #if defined(AST_MISDN_ENHANCEMENTS) 2633 static void print_facility_AddressScreened(
unsigned Level,
const struct FacAddressScreened *Address,
const struct misdn_bchannel *bc)
2635 const char *Spacing;
2637 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2638 chan_misdn_log(1, bc->
port,
" -->%s ScreeningIndicator:%d\n", Spacing, Address->ScreeningIndicator);
2639 print_facility_PartyNumber(Level, &Address->Party, bc);
2640 print_facility_Subaddress(Level, &Address->Subaddress, bc);
2644 #if defined(AST_MISDN_ENHANCEMENTS) 2645 static void print_facility_PresentedAddressScreened(
unsigned Level,
const struct FacPresentedAddressScreened *Presented,
const struct misdn_bchannel *bc)
2647 const char *Spacing;
2649 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2651 switch (Presented->Type) {
2654 print_facility_AddressScreened(Level + 2, &Presented->Address, bc);
2664 print_facility_AddressScreened(Level + 2, &Presented->Address, bc);
2672 #if defined(AST_MISDN_ENHANCEMENTS) 2673 static void print_facility_Q931_Bc_Hlc_Llc(
unsigned Level,
const struct Q931_Bc_Hlc_Llc *Q931ie,
const struct misdn_bchannel *bc)
2675 const char *Spacing;
2677 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2679 if (Q931ie->Bc.Length) {
2682 if (Q931ie->Hlc.Length) {
2685 if (Q931ie->Llc.Length) {
2691 #if defined(AST_MISDN_ENHANCEMENTS) 2692 static void print_facility_Q931_Bc_Hlc_Llc_Uu(
unsigned Level,
const struct Q931_Bc_Hlc_Llc_Uu *Q931ie,
const struct misdn_bchannel *bc)
2694 const char *Spacing;
2696 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2698 if (Q931ie->Bc.Length) {
2701 if (Q931ie->Hlc.Length) {
2704 if (Q931ie->Llc.Length) {
2707 if (Q931ie->UserInfo.Length) {
2708 chan_misdn_log(1, bc->
port,
" -->%s UserInfo Len:%d\n", Spacing, Q931ie->UserInfo.Length);
2713 #if defined(AST_MISDN_ENHANCEMENTS) 2714 static void print_facility_CallInformation(
unsigned Level,
const struct FacCallInformation *CallInfo,
const struct misdn_bchannel *bc)
2716 const char *Spacing;
2718 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2720 Spacing, CallInfo->CCBSReference);
2722 print_facility_Address(Level + 1, &CallInfo->AddressOfB, bc);
2723 print_facility_Q931_Bc_Hlc_Llc(Level, &CallInfo->Q931ie, bc);
2724 if (CallInfo->SubaddressOfA.Length) {
2726 print_facility_Subaddress(Level + 1, &CallInfo->SubaddressOfA, bc);
2731 #if defined(AST_MISDN_ENHANCEMENTS) 2732 static void print_facility_ServedUserNr(
unsigned Level,
const struct FacPartyNumber *Party,
const struct misdn_bchannel *bc)
2734 const char *Spacing;
2736 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2737 if (Party->LengthOfNumber) {
2738 print_facility_PartyNumber(Level, Party, bc);
2745 #if defined(AST_MISDN_ENHANCEMENTS) 2746 static void print_facility_IntResult(
unsigned Level,
const struct FacForwardingRecord *ForwardingRecord,
const struct misdn_bchannel *bc)
2748 const char *Spacing;
2750 Spacing = &Level_Spacing[
sizeof(Level_Spacing) - 1 - Level];
2753 ForwardingRecord->Procedure,
2754 ForwardingRecord->BasicService);
2756 print_facility_Address(Level + 1, &ForwardingRecord->ForwardedTo, bc);
2758 print_facility_ServedUserNr(Level + 1, &ForwardingRecord->ServedUser, bc);
2764 #if defined(AST_MISDN_ENHANCEMENTS) 2768 switch (fac->Function) {
2769 #if defined(AST_MISDN_ENHANCEMENTS) 2770 case Fac_ActivationDiversion:
2772 fac->u.ActivationDiversion.InvokeID);
2773 switch (fac->u.ActivationDiversion.ComponentType) {
2774 case FacComponent_Invoke:
2776 fac->u.ActivationDiversion.Component.Invoke.Procedure,
2777 fac->u.ActivationDiversion.Component.Invoke.BasicService);
2779 print_facility_Address(3, &fac->u.ActivationDiversion.Component.Invoke.ForwardedTo, bc);
2781 print_facility_ServedUserNr(3, &fac->u.ActivationDiversion.Component.Invoke.ServedUser, bc);
2783 case FacComponent_Result:
2790 case Fac_DeactivationDiversion:
2792 fac->u.DeactivationDiversion.InvokeID);
2793 switch (fac->u.DeactivationDiversion.ComponentType) {
2794 case FacComponent_Invoke:
2796 fac->u.DeactivationDiversion.Component.Invoke.Procedure,
2797 fac->u.DeactivationDiversion.Component.Invoke.BasicService);
2799 print_facility_ServedUserNr(3, &fac->u.DeactivationDiversion.Component.Invoke.ServedUser, bc);
2801 case FacComponent_Result:
2808 case Fac_ActivationStatusNotificationDiv:
2809 chan_misdn_log(1, bc->
port,
" --> ActivationStatusNotificationDiv: InvokeID:%d Procedure:%d BasicService:%d\n",
2810 fac->u.ActivationStatusNotificationDiv.InvokeID,
2811 fac->u.ActivationStatusNotificationDiv.Procedure,
2812 fac->u.ActivationStatusNotificationDiv.BasicService);
2814 print_facility_Address(2, &fac->u.ActivationStatusNotificationDiv.ForwardedTo, bc);
2816 print_facility_ServedUserNr(2, &fac->u.ActivationStatusNotificationDiv.ServedUser, bc);
2818 case Fac_DeactivationStatusNotificationDiv:
2819 chan_misdn_log(1, bc->
port,
" --> DeactivationStatusNotificationDiv: InvokeID:%d Procedure:%d BasicService:%d\n",
2820 fac->u.DeactivationStatusNotificationDiv.InvokeID,
2821 fac->u.DeactivationStatusNotificationDiv.Procedure,
2822 fac->u.DeactivationStatusNotificationDiv.BasicService);
2824 print_facility_ServedUserNr(2, &fac->u.DeactivationStatusNotificationDiv.ServedUser, bc);
2826 case Fac_InterrogationDiversion:
2828 fac->u.InterrogationDiversion.InvokeID);
2829 switch (fac->u.InterrogationDiversion.ComponentType) {
2830 case FacComponent_Invoke:
2832 fac->u.InterrogationDiversion.Component.Invoke.Procedure,
2833 fac->u.InterrogationDiversion.Component.Invoke.BasicService);
2835 print_facility_ServedUserNr(3, &fac->u.InterrogationDiversion.Component.Invoke.ServedUser, bc);
2837 case FacComponent_Result:
2839 if (fac->u.InterrogationDiversion.Component.Result.NumRecords) {
2840 for (Index = 0; Index < fac->u.InterrogationDiversion.Component.Result.NumRecords; ++Index) {
2842 print_facility_IntResult(3, &fac->u.InterrogationDiversion.Component.Result.List[Index], bc);
2850 case Fac_DiversionInformation:
2851 chan_misdn_log(1, bc->
port,
" --> DiversionInformation: InvokeID:%d Reason:%d BasicService:%d\n",
2852 fac->u.DiversionInformation.InvokeID,
2853 fac->u.DiversionInformation.DiversionReason,
2854 fac->u.DiversionInformation.BasicService);
2855 if (fac->u.DiversionInformation.ServedUserSubaddress.Length) {
2857 print_facility_Subaddress(2, &fac->u.DiversionInformation.ServedUserSubaddress, bc);
2859 if (fac->u.DiversionInformation.CallingAddressPresent) {
2861 print_facility_PresentedAddressScreened(2, &fac->u.DiversionInformation.CallingAddress, bc);
2863 if (fac->u.DiversionInformation.OriginalCalledPresent) {
2865 print_facility_PresentedNumberUnscreened(2, &fac->u.DiversionInformation.OriginalCalled, bc);
2867 if (fac->u.DiversionInformation.LastDivertingPresent) {
2869 print_facility_PresentedNumberUnscreened(2, &fac->u.DiversionInformation.LastDiverting, bc);
2871 if (fac->u.DiversionInformation.LastDivertingReasonPresent) {
2872 chan_misdn_log(1, bc->
port,
" --> LastDivertingReason:%d\n", fac->u.DiversionInformation.LastDivertingReason);
2874 if (fac->u.DiversionInformation.UserInfo.Length) {
2875 chan_misdn_log(1, bc->
port,
" --> UserInfo Length:%d\n", fac->u.DiversionInformation.UserInfo.Length);
2878 case Fac_CallDeflection:
2880 fac->u.CallDeflection.InvokeID);
2881 switch (fac->u.CallDeflection.ComponentType) {
2882 case FacComponent_Invoke:
2884 if (fac->u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent) {
2886 fac->u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser);
2889 print_facility_Address(3, &fac->u.CallDeflection.Component.Invoke.Deflection, bc);
2891 case FacComponent_Result:
2898 case Fac_CallRerouteing:
2900 fac->u.CallRerouteing.InvokeID);
2901 switch (fac->u.CallRerouteing.ComponentType) {
2902 case FacComponent_Invoke:
2904 fac->u.CallRerouteing.Component.Invoke.ReroutingReason,
2905 fac->u.CallRerouteing.Component.Invoke.ReroutingCounter);
2907 print_facility_Address(3, &fac->u.CallRerouteing.Component.Invoke.CalledAddress, bc);
2908 print_facility_Q931_Bc_Hlc_Llc_Uu(2, &fac->u.CallRerouteing.Component.Invoke.Q931ie, bc);
2910 print_facility_PresentedNumberUnscreened(3, &fac->u.CallRerouteing.Component.Invoke.LastRerouting, bc);
2912 fac->u.CallRerouteing.Component.Invoke.SubscriptionOption);
2913 if (fac->u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length) {
2915 print_facility_Subaddress(3, &fac->u.CallRerouteing.Component.Invoke.CallingPartySubaddress, bc);
2918 case FacComponent_Result:
2925 case Fac_InterrogateServedUserNumbers:
2927 fac->u.InterrogateServedUserNumbers.InvokeID);
2928 switch (fac->u.InterrogateServedUserNumbers.ComponentType) {
2929 case FacComponent_Invoke:
2932 case FacComponent_Result:
2934 if (fac->u.InterrogateServedUserNumbers.Component.Result.NumRecords) {
2935 for (Index = 0; Index < fac->u.InterrogateServedUserNumbers.Component.Result.NumRecords; ++Index) {
2937 print_facility_PartyNumber(3, &fac->u.InterrogateServedUserNumbers.Component.Result.List[Index], bc);
2945 case Fac_DivertingLegInformation1:
2946 chan_misdn_log(1, bc->
port,
" --> DivertingLegInformation1: InvokeID:%d Reason:%d SubscriptionOption:%d\n",
2947 fac->u.DivertingLegInformation1.InvokeID,
2948 fac->u.DivertingLegInformation1.DiversionReason,
2949 fac->u.DivertingLegInformation1.SubscriptionOption);
2950 if (fac->u.DivertingLegInformation1.DivertedToPresent) {
2952 print_facility_PresentedNumberUnscreened(2, &fac->u.DivertingLegInformation1.DivertedTo, bc);
2955 case Fac_DivertingLegInformation2:
2956 chan_misdn_log(1, bc->
port,
" --> DivertingLegInformation2: InvokeID:%d Reason:%d Count:%d\n",
2957 fac->u.DivertingLegInformation2.InvokeID,
2958 fac->u.DivertingLegInformation2.DiversionReason,
2959 fac->u.DivertingLegInformation2.DiversionCounter);
2960 if (fac->u.DivertingLegInformation2.DivertingPresent) {
2962 print_facility_PresentedNumberUnscreened(2, &fac->u.DivertingLegInformation2.Diverting, bc);
2964 if (fac->u.DivertingLegInformation2.OriginalCalledPresent) {
2966 print_facility_PresentedNumberUnscreened(2, &fac->u.DivertingLegInformation2.OriginalCalled, bc);
2969 case Fac_DivertingLegInformation3:
2970 chan_misdn_log(1, bc->
port,
" --> DivertingLegInformation3: InvokeID:%d PresentationAllowed:%d\n",
2971 fac->u.DivertingLegInformation3.InvokeID,
2972 fac->u.DivertingLegInformation3.PresentationAllowedIndicator);
2978 chan_misdn_log(1, bc->
port,
" --> calldeflect to: %s, presentable: %s\n", fac->u.CDeflection.DeflectedToNumber,
2979 fac->u.CDeflection.PresentationAllowed ?
"yes" :
"no");
2982 case Fac_AOCDCurrency:
2983 if (fac->u.AOCDcur.chargeNotAvailable) {
2985 }
else if (fac->u.AOCDcur.freeOfCharge) {
2987 }
else if (fac->u.AOCDchu.billingId >= 0) {
2988 chan_misdn_log(1, bc->
port,
" --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s billingId:%d\n",
2989 fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
2990 (fac->u.AOCDcur.typeOfChargingInfo == 0) ?
"subTotal" :
"total", fac->u.AOCDcur.billingId);
2992 chan_misdn_log(1, bc->
port,
" --> AOCD currency: currency:%s amount:%d multiplier:%d typeOfChargingInfo:%s\n",
2993 fac->u.AOCDcur.currency, fac->u.AOCDcur.currencyAmount, fac->u.AOCDcur.multiplier,
2994 (fac->u.AOCDcur.typeOfChargingInfo == 0) ?
"subTotal" :
"total");
2997 case Fac_AOCDChargingUnit:
2998 if (fac->u.AOCDchu.chargeNotAvailable) {
3000 }
else if (fac->u.AOCDchu.freeOfCharge) {
3002 }
else if (fac->u.AOCDchu.billingId >= 0) {
3003 chan_misdn_log(1, bc->
port,
" --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s billingId:%d\n",
3004 fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ?
"subTotal" :
"total", fac->u.AOCDchu.billingId);
3006 chan_misdn_log(1, bc->
port,
" --> AOCD charging unit: recordedUnits:%d typeOfChargingInfo:%s\n",
3007 fac->u.AOCDchu.recordedUnits, (fac->u.AOCDchu.typeOfChargingInfo == 0) ?
"subTotal" :
"total");
3010 #if defined(AST_MISDN_ENHANCEMENTS) 3013 fac->u.ERROR.invokeId, fac->u.ERROR.errorValue);
3017 fac->u.RESULT.InvokeID);
3020 if (fac->u.REJECT.InvokeIDPresent) {
3022 fac->u.REJECT.InvokeID, fac->u.REJECT.Code);
3025 fac->u.REJECT.Code);
3028 case Fac_EctExecute:
3030 fac->u.EctExecute.InvokeID);
3032 case Fac_ExplicitEctExecute:
3034 fac->u.ExplicitEctExecute.InvokeID,
3035 fac->u.ExplicitEctExecute.LinkID);
3037 case Fac_RequestSubaddress:
3039 fac->u.RequestSubaddress.InvokeID);
3041 case Fac_SubaddressTransfer:
3043 fac->u.SubaddressTransfer.InvokeID);
3044 print_facility_Subaddress(1, &fac->u.SubaddressTransfer.Subaddress, bc);
3046 case Fac_EctLinkIdRequest:
3048 fac->u.EctLinkIdRequest.InvokeID);
3049 switch (fac->u.EctLinkIdRequest.ComponentType) {
3050 case FacComponent_Invoke:
3053 case FacComponent_Result:
3055 fac->u.EctLinkIdRequest.Component.Result.LinkID);
3063 fac->u.EctInform.InvokeID,
3064 fac->u.EctInform.Status);
3065 if (fac->u.EctInform.RedirectionPresent) {
3067 print_facility_PresentedNumberUnscreened(2, &fac->u.EctInform.Redirection, bc);
3070 case Fac_EctLoopTest:
3072 fac->u.EctLoopTest.InvokeID);
3073 switch (fac->u.EctLoopTest.ComponentType) {
3074 case FacComponent_Invoke:
3076 fac->u.EctLoopTest.Component.Invoke.CallTransferID);
3078 case FacComponent_Result:
3080 fac->u.EctLoopTest.Component.Result.LoopResult);
3086 case Fac_StatusRequest:
3088 fac->u.StatusRequest.InvokeID);
3089 switch (fac->u.StatusRequest.ComponentType) {
3090 case FacComponent_Invoke:
3092 fac->u.StatusRequest.Component.Invoke.CompatibilityMode);
3094 case FacComponent_Result:
3096 fac->u.StatusRequest.Component.Result.Status);
3102 case Fac_CallInfoRetain:
3104 fac->u.CallInfoRetain.InvokeID, fac->u.CallInfoRetain.CallLinkageID);
3106 case Fac_CCBSDeactivate:
3108 fac->u.CCBSDeactivate.InvokeID);
3109 switch (fac->u.CCBSDeactivate.ComponentType) {
3110 case FacComponent_Invoke:
3112 fac->u.CCBSDeactivate.Component.Invoke.CCBSReference);
3114 case FacComponent_Result:
3122 chan_misdn_log(1, bc->
port,
" --> CCBSErase: InvokeID:%d, CCBSReference:%d RecallMode:%d, Reason:%d\n",
3123 fac->u.CCBSErase.InvokeID, fac->u.CCBSErase.CCBSReference,
3124 fac->u.CCBSErase.RecallMode, fac->u.CCBSErase.Reason);
3126 print_facility_Address(2, &fac->u.CCBSErase.AddressOfB, bc);
3127 print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSErase.Q931ie, bc);
3129 case Fac_CCBSRemoteUserFree:
3130 chan_misdn_log(1, bc->
port,
" --> CCBSRemoteUserFree: InvokeID:%d, CCBSReference:%d RecallMode:%d\n",
3131 fac->u.CCBSRemoteUserFree.InvokeID, fac->u.CCBSRemoteUserFree.CCBSReference,
3132 fac->u.CCBSRemoteUserFree.RecallMode);
3134 print_facility_Address(2, &fac->u.CCBSRemoteUserFree.AddressOfB, bc);
3135 print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSRemoteUserFree.Q931ie, bc);
3139 fac->u.CCBSCall.InvokeID, fac->u.CCBSCall.CCBSReference);
3141 case Fac_CCBSStatusRequest:
3143 fac->u.CCBSStatusRequest.InvokeID);
3144 switch (fac->u.CCBSStatusRequest.ComponentType) {
3145 case FacComponent_Invoke:
3147 fac->u.CCBSStatusRequest.Component.Invoke.CCBSReference,
3148 fac->u.CCBSStatusRequest.Component.Invoke.RecallMode);
3149 print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCBSStatusRequest.Component.Invoke.Q931ie, bc);
3151 case FacComponent_Result:
3153 fac->u.CCBSStatusRequest.Component.Result.Free);
3160 chan_misdn_log(1, bc->
port,
" --> CCBSBFree: InvokeID:%d, CCBSReference:%d RecallMode:%d\n",
3161 fac->u.CCBSBFree.InvokeID, fac->u.CCBSBFree.CCBSReference,
3162 fac->u.CCBSBFree.RecallMode);
3164 print_facility_Address(2, &fac->u.CCBSBFree.AddressOfB, bc);
3165 print_facility_Q931_Bc_Hlc_Llc(1, &fac->u.CCBSBFree.Q931ie, bc);
3167 case Fac_EraseCallLinkageID:
3169 fac->u.EraseCallLinkageID.InvokeID, fac->u.EraseCallLinkageID.CallLinkageID);
3171 case Fac_CCBSStopAlerting:
3172 chan_misdn_log(1, bc->
port,
" --> CCBSStopAlerting: InvokeID:%d, CCBSReference:%d\n",
3173 fac->u.CCBSStopAlerting.InvokeID, fac->u.CCBSStopAlerting.CCBSReference);
3175 case Fac_CCBSRequest:
3177 fac->u.CCBSRequest.InvokeID);
3178 switch (fac->u.CCBSRequest.ComponentType) {
3179 case FacComponent_Invoke:
3181 fac->u.CCBSRequest.Component.Invoke.CallLinkageID);
3183 case FacComponent_Result:
3185 fac->u.CCBSRequest.Component.Result.CCBSReference,
3186 fac->u.CCBSRequest.Component.Result.RecallMode);
3192 case Fac_CCBSInterrogate:
3194 fac->u.CCBSInterrogate.InvokeID);
3195 switch (fac->u.CCBSInterrogate.ComponentType) {
3196 case FacComponent_Invoke:
3198 if (fac->u.CCBSInterrogate.Component.Invoke.CCBSReferencePresent) {
3200 fac->u.CCBSInterrogate.Component.Invoke.CCBSReference);
3202 if (fac->u.CCBSInterrogate.Component.Invoke.AParty.LengthOfNumber) {
3204 print_facility_PartyNumber(3, &fac->u.CCBSInterrogate.Component.Invoke.AParty, bc);
3207 case FacComponent_Result:
3209 fac->u.CCBSInterrogate.Component.Result.RecallMode);
3210 if (fac->u.CCBSInterrogate.Component.Result.NumRecords) {
3211 for (Index = 0; Index < fac->u.CCBSInterrogate.Component.Result.NumRecords; ++Index) {
3213 print_facility_CallInformation(3, &fac->u.CCBSInterrogate.Component.Result.CallDetails[Index], bc);
3221 case Fac_CCNRRequest:
3223 fac->u.CCNRRequest.InvokeID);
3224 switch (fac->u.CCNRRequest.ComponentType) {
3225 case FacComponent_Invoke:
3227 fac->u.CCNRRequest.Component.Invoke.CallLinkageID);
3229 case FacComponent_Result:
3231 fac->u.CCNRRequest.Component.Result.CCBSReference,
3232 fac->u.CCNRRequest.Component.Result.RecallMode);
3238 case Fac_CCNRInterrogate:
3240 fac->u.CCNRInterrogate.InvokeID);
3241 switch (fac->u.CCNRInterrogate.ComponentType) {
3242 case FacComponent_Invoke:
3244 if (fac->u.CCNRInterrogate.Component.Invoke.CCBSReferencePresent) {
3246 fac->u.CCNRInterrogate.Component.Invoke.CCBSReference);
3248 if (fac->u.CCNRInterrogate.Component.Invoke.AParty.LengthOfNumber) {
3250 print_facility_PartyNumber(3, &fac->u.CCNRInterrogate.Component.Invoke.AParty, bc);
3253 case FacComponent_Result:
3255 fac->u.CCNRInterrogate.Component.Result.RecallMode);
3256 if (fac->u.CCNRInterrogate.Component.Result.NumRecords) {
3257 for (Index = 0; Index < fac->u.CCNRInterrogate.Component.Result.NumRecords; ++Index) {
3259 print_facility_CallInformation(3, &fac->u.CCNRInterrogate.Component.Result.CallDetails[Index], bc);
3267 case Fac_CCBS_T_Call:
3269 fac->u.CCBS_T_Call.InvokeID);
3271 case Fac_CCBS_T_Suspend:
3273 fac->u.CCBS_T_Suspend.InvokeID);
3275 case Fac_CCBS_T_Resume:
3277 fac->u.CCBS_T_Resume.InvokeID);
3279 case Fac_CCBS_T_RemoteUserFree:
3281 fac->u.CCBS_T_RemoteUserFree.InvokeID);
3283 case Fac_CCBS_T_Available:
3285 fac->u.CCBS_T_Available.InvokeID);
3287 case Fac_CCBS_T_Request:
3289 fac->u.CCBS_T_Request.InvokeID);
3290 switch (fac->u.CCBS_T_Request.ComponentType) {
3291 case FacComponent_Invoke:
3294 print_facility_Address(3, &fac->u.CCBS_T_Request.Component.Invoke.Destination, bc);
3295 print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCBS_T_Request.Component.Invoke.Q931ie, bc);
3296 if (fac->u.CCBS_T_Request.Component.Invoke.RetentionSupported) {
3299 if (fac->u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent) {
3301 fac->u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator);
3303 if (fac->u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber) {
3305 print_facility_Address(3, &fac->u.CCBS_T_Request.Component.Invoke.Originating, bc);
3308 case FacComponent_Result:
3310 fac->u.CCBS_T_Request.Component.Result.RetentionSupported);
3316 case Fac_CCNR_T_Request:
3318 fac->u.CCNR_T_Request.InvokeID);
3319 switch (fac->u.CCNR_T_Request.ComponentType) {
3320 case FacComponent_Invoke:
3323 print_facility_Address(3, &fac->u.CCNR_T_Request.Component.Invoke.Destination, bc);
3324 print_facility_Q931_Bc_Hlc_Llc(2, &fac->u.CCNR_T_Request.Component.Invoke.Q931ie, bc);
3325 if (fac->u.CCNR_T_Request.Component.Invoke.RetentionSupported) {
3328 if (fac->u.CCNR_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent) {
3330 fac->u.CCNR_T_Request.Component.Invoke.PresentationAllowedIndicator);
3332 if (fac->u.CCNR_T_Request.Component.Invoke.Originating.Party.LengthOfNumber) {
3334 print_facility_Address(3, &fac->u.CCNR_T_Request.Component.Invoke.Originating, bc);
3337 case FacComponent_Result:
3339 fac->u.CCNR_T_Request.Component.Result.RetentionSupported);
3388 len_prefix = strlen(str_prefix);
3393 len_main = strlen(str_main);
3394 len_total = len_prefix + len_main;
3395 if (size <= len_total) {
3397 len_over = len_total + 1 -
size;
3398 if (len_over <= len_main) {
3399 len_main -= len_over;
3401 len_over -= len_main;
3403 len_prefix -= len_over;
3407 memmove(str_main + len_prefix, str_main, len_main);
3409 memcpy(str_main, str_prefix, len_prefix);
3410 str_main[len_prefix + len_main] =
'\0';
3430 switch (number_type) {
3453 misdn_cfg_get(port, type_prefix, num_prefix,
sizeof(num_prefix));
3477 case Fac_AOCDCurrency:
3489 if (bc->
AOCD.
currency.billingId >= 0 && snprintf(buf,
sizeof(buf),
"%d", bc->
AOCD.
currency.billingId) <
sizeof(buf)) {
3496 case Fac_AOCDChargingUnit:
3506 if (snprintf(buf,
sizeof(buf),
"%d", bc->
AOCD.
chargingUnit.recordedUnits) <
sizeof(buf)) {
3531 struct sigaction sa;
3534 sa.sa_flags = SA_NODEFER;
3535 sigemptyset(&sa.sa_mask);
3536 sigaddset(&sa.sa_mask, SIGUSR1);
3537 sigaction(SIGUSR1, &sa,
NULL);
3539 sem_post((sem_t *)data);
3546 if (poll(
NULL, 0, wait) < 0) {
3559 if (sem_init(&blocker, 0, 0)) {
3560 perror(
"chan_misdn: Failed to initialize semaphore!");
3569 while (sem_wait(&blocker) && --i) {
3571 sem_destroy(&blocker);
3579 cb_log(4, 0,
"Joining misdn_tasks thread\n");
3621 const int *data = vdata;
3630 struct timeval tv_end, tv_now;
3668 goto misdn_overlap_dial_task_disconnect;
3671 misdn_overlap_dial_task_disconnect:
3683 static const char *
const dtmf_tones[] = {
3685 "!941+1336/100,!0/100",
3686 "!697+1209/100,!0/100",
3687 "!697+1336/100,!0/100",
3688 "!697+1477/100,!0/100",
3689 "!770+1209/100,!0/100",
3690 "!770+1336/100,!0/100",
3691 "!770+1477/100,!0/100",
3692 "!852+1209/100,!0/100",
3693 "!852+1336/100,!0/100",
3694 "!852+1477/100,!0/100",
3695 "!697+1633/100,!0/100",
3696 "!770+1633/100,!0/100",
3697 "!852+1633/100,!0/100",
3698 "!941+1633/100,!0/100",
3699 "!941+1209/100,!0/100",
3700 "!941+1477/100,!0/100",
3705 if (digit >=
'0' && digit <=
'9') {
3707 }
else if (digit >=
'A' && digit <=
'D') {
3709 }
else if (digit ==
'*') {
3711 }
else if (digit ==
'#') {
3726 e->
command =
"misdn set debug [on|off]";
3728 "Usage: misdn set debug {on|off|<level>} [only] | [port <port> [only]]\n" 3729 " Set the debug level of the mISDN channel.\n";
3739 if (!strcasecmp(a->
argv[3],
"on")) {
3741 }
else if (!strcasecmp(a->
argv[3],
"off")) {
3743 }
else if (isdigit(a->
argv[3][0])) {
3744 level = atoi(a->
argv[3]);
3756 if (strncasecmp(a->
argv[4],
"only", strlen(a->
argv[4]))) {
3764 misdn_debug[i] = level;
3765 misdn_debug_only[i] = only;
3767 ast_cli(a->
fd,
"changing debug level for all ports to %d%s\n", misdn_debug[0], only ?
" (only)" :
"");
3774 if (strncasecmp(a->
argv[4],
"port", strlen(a->
argv[4])))
3776 port = atoi(a->
argv[5]);
3777 if (port <= 0 || port > max_ports) {
3778 switch (max_ports) {
3780 ast_cli(a->
fd,
"port number not valid! no ports available so you won't get lucky with any number here...\n");
3783 ast_cli(a->
fd,
"port number not valid! only port 1 is available.\n");
3786 ast_cli(a->
fd,
"port number not valid! only ports 1 to %d are available.\n", max_ports);
3791 if (strncasecmp(a->
argv[6],
"only", strlen(a->
argv[6]))) {
3794 misdn_debug_only[port] = 1;
3797 misdn_debug_only[port] = 0;
3799 misdn_debug[port] = level;
3800 ast_cli(a->
fd,
"changing debug level to %d%s for port %d\n", misdn_debug[port], misdn_debug_only[port] ?
" (only)" :
"", port);
3811 e->
command =
"misdn set crypt debug";
3813 "Usage: misdn set crypt debug <level>\n" 3814 " Set the crypt debug level of the mISDN channel. Level\n" 3815 " must be 1 or 2.\n";
3834 e->
command =
"misdn port block";
3836 "Usage: misdn port block <port>\n" 3837 " Block the specified port by <port>.\n";
3856 e->
command =
"misdn port unblock";
3858 "Usage: misdn port unblock <port>\n" 3859 " Unblock the port specified by <port>.\n";
3878 e->
command =
"misdn restart port";
3880 "Usage: misdn restart port <port>\n" 3881 " Restart the given port.\n";
3900 e->
command =
"misdn restart pid";
3902 "Usage: misdn restart pid <pid>\n" 3903 " Restart the given pid\n";
3924 "Usage: misdn port up <port>\n" 3925 " Try to establish L1 on the given port.\n";
3944 e->
command =
"misdn port down";
3946 "Usage: misdn port down <port>\n" 3947 " Try to deactivate the L1 on the given port.\n";
3981 ast_cli(fd,
"[%s] %s (Default: %s)\n\t%s\n", section, name, def, desc);
3983 ast_cli(fd,
"[%s] %s\n\t%s\n", section, name, desc);
3997 e->
command =
"misdn show config";
3999 "Usage: misdn show config [<port> | description <config element> | descriptions [general|ports]]\n" 4000 " Use 0 for <port> to only print the general config.\n";
4007 if (!strcmp(a->
argv[3],
"description")) {
4018 }
else if (!strcmp(a->
argv[3],
"descriptions")) {
4019 if ((a->
argc == 4) || ((a->
argc == 5) && !strcmp(a->
argv[4],
"general"))) {
4026 if ((a->
argc == 4) || ((a->
argc == 5) && !strcmp(a->
argv[4],
"ports"))) {
4034 }
else if (!sscanf(a->
argv[3],
"%5d", &onlyport) || onlyport < 0) {
4040 if (a->
argc == 3 || onlyport == 0) {
4041 ast_cli(a->
fd,
"mISDN General-Config:\n");
4044 ast_cli(a->
fd,
"%-36s%s", buffer, !(linebreak % 2) ?
"\n" :
"");
4056 ast_cli(a->
fd,
"%-36s%s", buffer, !(linebreak % 2) ?
"\n" :
"");
4064 ast_cli(a->
fd,
"[PORT %d]\n", onlyport);
4067 ast_cli(a->
fd,
"%-36s%s", buffer, !(linebreak % 2) ?
"\n" :
"");
4071 ast_cli(a->
fd,
"Port %d is not active!\n", onlyport);
4105 static char state[8];
4111 for (i = 0; i <
ARRAY_LEN(state_array); i++) {
4112 if (state_array[i].state == p->
state) {
4113 return state_array[i].
txt;
4117 snprintf(state,
sizeof(state),
"%d", p->
state) ;
4139 misdn_debug[i] = cfg_debug;
4140 misdn_debug_only[i] = 0;
4150 "Usage: misdn reload\n" 4151 " Reload internal mISDN config, read from the config\n" 4162 ast_cli(a->
fd,
"Reloading mISDN configuration\n");
4172 "* Pid:%d Port:%d Ch:%d Mode:%s Orig:%s dialed:%s\n" 4173 " --> caller:\"%s\" <%s>\n" 4174 " --> redirecting-from:\"%s\" <%s>\n" 4175 " --> redirecting-to:\"%s\" <%s>\n" 4176 " --> context:%s state:%s\n",
4180 bc->
nt ?
"NT" :
"TE",
4193 if (misdn_debug[bc->
port] > 0) {
4195 " --> astname: %s\n" 4196 " --> ch_l3id: %x\n" 4197 " --> ch_addr: %x\n" 4198 " --> bc_addr: %x\n" 4199 " --> bc_l3id: %x\n" 4200 " --> display: %s\n" 4201 " --> activated: %d\n" 4203 " --> capability: %s\n" 4205 " --> pipeline: %s\n" 4207 " --> echo_cancel: %d\n" 4209 " --> notone : rx %d tx:%d\n" 4210 " --> bc_hold: %d\n",
4236 e->
command =
"misdn show channels";
4238 "Usage: misdn show channels\n" 4239 " Show the internal mISDN channel list\n";
4249 ast_cli(a->
fd,
"Channel List: %p\n", cl_te);
4258 for (help = cl_te; help; help = help->
next) {
4263 ast_cli(a->
fd,
"chan_list obj. with l3id:%x has no bc and no ast Leg\n", help->
l3id);
4266 ast_cli(a->
fd,
"bc with pid:%d has no Ast Leg\n", bc->
pid);
4269 if (misdn_debug[0] > 2) {
4270 ast_cli(a->
fd,
"Bc:%p Ast:%p\n", bc, ast);
4276 ast_cli(a->
fd,
"ITS A HELD CALL BC:\n");
4279 " --> caller:\"%s\" <%s>\n" 4280 " --> hold_port: %d\n" 4281 " --> hold_channel: %d\n",
4290 ast_cli(a->
fd,
"* Channel in unknown STATE !!! Exten:%s, Callerid:%s\n",
4309 e->
command =
"misdn show channel";
4311 "Usage: misdn show channel <channel>\n" 4312 " Show an internal mISDN channel\n.";
4323 for (help = cl_te; help; help = help->
next) {
4343 e->
command =
"misdn set tics";
4345 "Usage: misdn set tics <value>\n";
4367 e->
command =
"misdn show stacks";
4369 "Usage: misdn show stacks\n" 4370 " Show internal mISDN stack_list.\n";
4386 ast_cli(a->
fd,
" %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ?
"(only)" :
"");
4398 e->
command =
"misdn show ports stats";
4400 "Usage: misdn show ports stats\n" 4401 " Show mISDNs channel's call statistics per port.\n";
4411 ast_cli(a->
fd,
"Port\tin_calls\tout_calls\n");
4414 ast_cli(a->
fd,
"%d\t%d\t\t%d\n", port, misdn_in_calls[port], misdn_out_calls[port]);
4428 e->
command =
"misdn show port";
4430 "Usage: misdn show port <port>\n" 4431 " Show detailed information for given port.\n";
4441 port = atoi(a->
argv[3]);
4445 ast_cli(a->
fd,
" %s Debug:%d%s\n", buf, misdn_debug[port], misdn_debug_only[port] ?
"(only)" :
"");
4450 #if defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES) 4451 static const struct FacParm Fac_Msgs[] = {
4453 [0].Function = Fac_ERROR,
4454 [0].u.ERROR.invokeId = 8,
4455 [0].u.ERROR.errorValue = FacError_CCBS_AlreadyAccepted,
4457 [1].Function = Fac_RESULT,
4458 [1].u.RESULT.InvokeID = 9,
4460 [2].Function = Fac_REJECT,
4461 [2].u.REJECT.Code = FacReject_Gen_BadlyStructuredComponent,
4463 [3].Function = Fac_REJECT,
4464 [3].u.REJECT.InvokeIDPresent = 1,
4465 [3].u.REJECT.InvokeID = 10,
4466 [3].u.REJECT.Code = FacReject_Inv_InitiatorReleasing,
4468 [4].Function = Fac_REJECT,
4469 [4].u.REJECT.InvokeIDPresent = 1,
4470 [4].u.REJECT.InvokeID = 11,
4471 [4].u.REJECT.Code = FacReject_Res_MistypedResult,
4473 [5].Function = Fac_REJECT,
4474 [5].u.REJECT.InvokeIDPresent = 1,
4475 [5].u.REJECT.InvokeID = 12,
4476 [5].u.REJECT.Code = FacReject_Err_ErrorResponseUnexpected,
4478 [6].Function = Fac_StatusRequest,
4479 [6].u.StatusRequest.InvokeID = 13,
4480 [6].u.StatusRequest.ComponentType = FacComponent_Invoke,
4481 [6].u.StatusRequest.Component.Invoke.Q931ie.Bc.Length = 2,
4482 [6].u.StatusRequest.Component.Invoke.Q931ie.Bc.Contents =
"AB",
4483 [6].u.StatusRequest.Component.Invoke.Q931ie.Llc.Length = 3,
4484 [6].u.StatusRequest.Component.Invoke.Q931ie.Llc.Contents =
"CDE",
4485 [6].u.StatusRequest.Component.Invoke.Q931ie.Hlc.Length = 4,
4486 [6].u.StatusRequest.Component.Invoke.Q931ie.Hlc.Contents =
"FGHI",
4487 [6].u.StatusRequest.Component.Invoke.CompatibilityMode = 1,
4489 [7].Function = Fac_StatusRequest,
4490 [7].u.StatusRequest.InvokeID = 14,
4491 [7].u.StatusRequest.ComponentType = FacComponent_Result,
4492 [7].u.StatusRequest.Component.Result.Status = 2,
4494 [8].Function = Fac_CallInfoRetain,
4495 [8].u.CallInfoRetain.InvokeID = 15,
4496 [8].u.CallInfoRetain.CallLinkageID = 115,
4498 [9].Function = Fac_EraseCallLinkageID,
4499 [9].u.EraseCallLinkageID.InvokeID = 16,
4500 [9].u.EraseCallLinkageID.CallLinkageID = 105,
4502 [10].Function = Fac_CCBSDeactivate,
4503 [10].u.CCBSDeactivate.InvokeID = 17,
4504 [10].u.CCBSDeactivate.ComponentType = FacComponent_Invoke,
4505 [10].u.CCBSDeactivate.Component.Invoke.CCBSReference = 2,
4507 [11].Function = Fac_CCBSDeactivate,
4508 [11].u.CCBSDeactivate.InvokeID = 18,
4509 [11].u.CCBSDeactivate.ComponentType = FacComponent_Result,
4511 [12].Function = Fac_CCBSErase,
4512 [12].u.CCBSErase.InvokeID = 19,
4513 [12].u.CCBSErase.Q931ie.Bc.Length = 2,
4514 [12].u.CCBSErase.Q931ie.Bc.Contents =
"JK",
4515 [12].u.CCBSErase.AddressOfB.Party.Type = 0,
4516 [12].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 5,
4517 [12].u.CCBSErase.AddressOfB.Party.Number =
"33403",
4518 [12].u.CCBSErase.AddressOfB.Subaddress.Type = 0,
4519 [12].u.CCBSErase.AddressOfB.Subaddress.Length = 4,
4520 [12].u.CCBSErase.AddressOfB.Subaddress.u.UserSpecified.Information =
"3748",
4521 [12].u.CCBSErase.RecallMode = 1,
4522 [12].u.CCBSErase.CCBSReference = 102,
4523 [12].u.CCBSErase.Reason = 3,
4525 [13].Function = Fac_CCBSErase,
4526 [13].u.CCBSErase.InvokeID = 20,
4527 [13].u.CCBSErase.Q931ie.Bc.Length = 2,
4528 [13].u.CCBSErase.Q931ie.Bc.Contents =
"JK",
4529 [13].u.CCBSErase.AddressOfB.Party.Type = 1,
4530 [13].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 11,
4531 [13].u.CCBSErase.AddressOfB.Party.TypeOfNumber = 1,
4532 [13].u.CCBSErase.AddressOfB.Party.Number =
"18003020102",
4533 [13].u.CCBSErase.AddressOfB.Subaddress.Type = 0,
4534 [13].u.CCBSErase.AddressOfB.Subaddress.Length = 4,
4535 [13].u.CCBSErase.AddressOfB.Subaddress.u.UserSpecified.OddCountPresent = 1,
4536 [13].u.CCBSErase.AddressOfB.Subaddress.u.UserSpecified.OddCount = 1,
4537 [13].u.CCBSErase.AddressOfB.Subaddress.u.UserSpecified.Information =
"3748",
4538 [13].u.CCBSErase.RecallMode = 1,
4539 [13].u.CCBSErase.CCBSReference = 102,
4540 [13].u.CCBSErase.Reason = 3,
4542 [14].Function = Fac_CCBSErase,
4543 [14].u.CCBSErase.InvokeID = 21,
4544 [14].u.CCBSErase.Q931ie.Bc.Length = 2,
4545 [14].u.CCBSErase.Q931ie.Bc.Contents =
"JK",
4546 [14].u.CCBSErase.AddressOfB.Party.Type = 2,
4547 [14].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 4,
4548 [14].u.CCBSErase.AddressOfB.Party.Number =
"1803",
4549 [14].u.CCBSErase.AddressOfB.Subaddress.Type = 1,
4550 [14].u.CCBSErase.AddressOfB.Subaddress.Length = 4,
4551 [14].u.CCBSErase.AddressOfB.Subaddress.u.Nsap =
"6492",
4552 [14].u.CCBSErase.RecallMode = 1,
4553 [14].u.CCBSErase.CCBSReference = 102,
4554 [14].u.CCBSErase.Reason = 3,
4556 [15].Function = Fac_CCBSErase,
4557 [15].u.CCBSErase.InvokeID = 22,
4558 [15].u.CCBSErase.Q931ie.Bc.Length = 2,
4559 [15].u.CCBSErase.Q931ie.Bc.Contents =
"JK",
4560 [15].u.CCBSErase.AddressOfB.Party.Type = 3,
4561 [15].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 4,
4562 [15].u.CCBSErase.AddressOfB.Party.Number =
"1803",
4563 [15].u.CCBSErase.RecallMode = 1,
4564 [15].u.CCBSErase.CCBSReference = 102,
4565 [15].u.CCBSErase.Reason = 3,
4567 [16].Function = Fac_CCBSErase,
4568 [16].u.CCBSErase.InvokeID = 23,
4569 [16].u.CCBSErase.Q931ie.Bc.Length = 2,
4570 [16].u.CCBSErase.Q931ie.Bc.Contents =
"JK",
4571 [16].u.CCBSErase.AddressOfB.Party.Type = 4,
4572 [16].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 4,
4573 [16].u.CCBSErase.AddressOfB.Party.Number =
"1803",
4574 [16].u.CCBSErase.RecallMode = 1,
4575 [16].u.CCBSErase.CCBSReference = 102,
4576 [16].u.CCBSErase.Reason = 3,
4578 [17].Function = Fac_CCBSErase,
4579 [17].u.CCBSErase.InvokeID = 24,
4580 [17].u.CCBSErase.Q931ie.Bc.Length = 2,
4581 [17].u.CCBSErase.Q931ie.Bc.Contents =
"JK",
4582 [17].u.CCBSErase.AddressOfB.Party.Type = 5,
4583 [17].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 11,
4584 [17].u.CCBSErase.AddressOfB.Party.TypeOfNumber = 4,
4585 [17].u.CCBSErase.AddressOfB.Party.Number =
"18003020102",
4586 [17].u.CCBSErase.RecallMode = 1,
4587 [17].u.CCBSErase.CCBSReference = 102,
4588 [17].u.CCBSErase.Reason = 3,
4590 [18].Function = Fac_CCBSErase,
4591 [18].u.CCBSErase.InvokeID = 25,
4592 [18].u.CCBSErase.Q931ie.Bc.Length = 2,
4593 [18].u.CCBSErase.Q931ie.Bc.Contents =
"JK",
4594 [18].u.CCBSErase.AddressOfB.Party.Type = 8,
4595 [18].u.CCBSErase.AddressOfB.Party.LengthOfNumber = 4,
4596 [18].u.CCBSErase.AddressOfB.Party.Number =
"1803",
4597 [18].u.CCBSErase.RecallMode = 1,
4598 [18].u.CCBSErase.CCBSReference = 102,
4599 [18].u.CCBSErase.Reason = 3,
4601 [19].Function = Fac_CCBSRemoteUserFree,
4602 [19].u.CCBSRemoteUserFree.InvokeID = 26,
4603 [19].u.CCBSRemoteUserFree.Q931ie.Bc.Length = 2,
4604 [19].u.CCBSRemoteUserFree.Q931ie.Bc.Contents =
"JK",
4605 [19].u.CCBSRemoteUserFree.AddressOfB.Party.Type = 8,
4606 [19].u.CCBSRemoteUserFree.AddressOfB.Party.LengthOfNumber = 4,
4607 [19].u.CCBSRemoteUserFree.AddressOfB.Party.Number =
"1803",
4608 [19].u.CCBSRemoteUserFree.RecallMode = 1,
4609 [19].u.CCBSRemoteUserFree.CCBSReference = 102,
4611 [20].Function = Fac_CCBSCall,
4612 [20].u.CCBSCall.InvokeID = 27,
4613 [20].u.CCBSCall.CCBSReference = 115,
4615 [21].Function = Fac_CCBSStatusRequest,
4616 [21].u.CCBSStatusRequest.InvokeID = 28,
4617 [21].u.CCBSStatusRequest.ComponentType = FacComponent_Invoke,
4618 [21].u.CCBSStatusRequest.Component.Invoke.Q931ie.Bc.Length = 2,
4619 [21].u.CCBSStatusRequest.Component.Invoke.Q931ie.Bc.Contents =
"JK",
4620 [21].u.CCBSStatusRequest.Component.Invoke.RecallMode = 1,
4621 [21].u.CCBSStatusRequest.Component.Invoke.CCBSReference = 102,
4623 [22].Function = Fac_CCBSStatusRequest,
4624 [22].u.CCBSStatusRequest.InvokeID = 29,
4625 [22].u.CCBSStatusRequest.ComponentType = FacComponent_Result,
4626 [22].u.CCBSStatusRequest.Component.Result.Free = 1,
4628 [23].Function = Fac_CCBSBFree,
4629 [23].u.CCBSBFree.InvokeID = 30,
4630 [23].u.CCBSBFree.Q931ie.Bc.Length = 2,
4631 [23].u.CCBSBFree.Q931ie.Bc.Contents =
"JK",
4632 [23].u.CCBSBFree.AddressOfB.Party.Type = 8,
4633 [23].u.CCBSBFree.AddressOfB.Party.LengthOfNumber = 4,
4634 [23].u.CCBSBFree.AddressOfB.Party.Number =
"1803",
4635 [23].u.CCBSBFree.RecallMode = 1,
4636 [23].u.CCBSBFree.CCBSReference = 14,
4638 [24].Function = Fac_CCBSStopAlerting,
4639 [24].u.CCBSStopAlerting.InvokeID = 31,
4640 [24].u.CCBSStopAlerting.CCBSReference = 37,
4642 [25].Function = Fac_CCBSRequest,
4643 [25].u.CCBSRequest.InvokeID = 32,
4644 [25].u.CCBSRequest.ComponentType = FacComponent_Invoke,
4645 [25].u.CCBSRequest.Component.Invoke.CallLinkageID = 57,
4647 [26].Function = Fac_CCBSRequest,
4648 [26].u.CCBSRequest.InvokeID = 33,
4649 [26].u.CCBSRequest.ComponentType = FacComponent_Result,
4650 [26].u.CCBSRequest.Component.Result.RecallMode = 1,
4651 [26].u.CCBSRequest.Component.Result.CCBSReference = 102,
4653 [27].Function = Fac_CCBSInterrogate,
4654 [27].u.CCBSInterrogate.InvokeID = 34,
4655 [27].u.CCBSInterrogate.ComponentType = FacComponent_Invoke,
4656 [27].u.CCBSInterrogate.Component.Invoke.AParty.Type = 8,
4657 [27].u.CCBSInterrogate.Component.Invoke.AParty.LengthOfNumber = 4,
4658 [27].u.CCBSInterrogate.Component.Invoke.AParty.Number =
"1803",
4659 [27].u.CCBSInterrogate.Component.Invoke.CCBSReferencePresent = 1,
4660 [27].u.CCBSInterrogate.Component.Invoke.CCBSReference = 76,
4662 [28].Function = Fac_CCBSInterrogate,
4663 [28].u.CCBSInterrogate.InvokeID = 35,
4664 [28].u.CCBSInterrogate.ComponentType = FacComponent_Invoke,
4665 [28].u.CCBSInterrogate.Component.Invoke.AParty.Type = 8,
4666 [28].u.CCBSInterrogate.Component.Invoke.AParty.LengthOfNumber = 4,
4667 [28].u.CCBSInterrogate.Component.Invoke.AParty.Number =
"1803",
4669 [29].Function = Fac_CCBSInterrogate,
4670 [29].u.CCBSInterrogate.InvokeID = 36,
4671 [29].u.CCBSInterrogate.ComponentType = FacComponent_Invoke,
4672 [29].u.CCBSInterrogate.Component.Invoke.CCBSReferencePresent = 1,
4673 [29].u.CCBSInterrogate.Component.Invoke.CCBSReference = 76,
4675 [30].Function = Fac_CCBSInterrogate,
4676 [30].u.CCBSInterrogate.InvokeID = 37,
4677 [30].u.CCBSInterrogate.ComponentType = FacComponent_Invoke,
4679 [31].Function = Fac_CCBSInterrogate,
4680 [31].u.CCBSInterrogate.InvokeID = 38,
4681 [31].u.CCBSInterrogate.ComponentType = FacComponent_Result,
4682 [31].u.CCBSInterrogate.Component.Result.RecallMode = 1,
4684 [32].Function = Fac_CCBSInterrogate,
4685 [32].u.CCBSInterrogate.InvokeID = 39,
4686 [32].u.CCBSInterrogate.ComponentType = FacComponent_Result,
4687 [32].u.CCBSInterrogate.Component.Result.RecallMode = 1,
4688 [32].u.CCBSInterrogate.Component.Result.NumRecords = 1,
4689 [32].u.CCBSInterrogate.Component.Result.CallDetails[0].CCBSReference = 12,
4690 [32].u.CCBSInterrogate.Component.Result.CallDetails[0].Q931ie.Bc.Length = 2,
4691 [32].u.CCBSInterrogate.Component.Result.CallDetails[0].Q931ie.Bc.Contents =
"JK",
4692 [32].u.CCBSInterrogate.Component.Result.CallDetails[0].AddressOfB.Party.Type = 8,
4693 [32].u.CCBSInterrogate.Component.Result.CallDetails[0].AddressOfB.Party.LengthOfNumber = 4,
4694 [32].u.CCBSInterrogate.Component.Result.CallDetails[0].AddressOfB.Party.Number =
"1803",
4695 [32].u.CCBSInterrogate.Component.Result.CallDetails[0].SubaddressOfA.Type = 1,
4696 [32].u.CCBSInterrogate.Component.Result.CallDetails[0].SubaddressOfA.Length = 4,
4697 [32].u.CCBSInterrogate.Component.Result.CallDetails[0].SubaddressOfA.u.Nsap =
"6492",
4699 [33].Function = Fac_CCBSInterrogate,
4700 [33].u.CCBSInterrogate.InvokeID = 40,
4701 [33].u.CCBSInterrogate.ComponentType = FacComponent_Result,
4702 [33].u.CCBSInterrogate.Component.Result.RecallMode = 1,
4703 [33].u.CCBSInterrogate.Component.Result.NumRecords = 2,
4704 [33].u.CCBSInterrogate.Component.Result.CallDetails[0].CCBSReference = 12,
4705 [33].u.CCBSInterrogate.Component.Result.CallDetails[0].Q931ie.Bc.Length = 2,
4706 [33].u.CCBSInterrogate.Component.Result.CallDetails[0].Q931ie.Bc.Contents =
"JK",
4707 [33].u.CCBSInterrogate.Component.Result.CallDetails[0].AddressOfB.Party.Type = 8,
4708 [33].u.CCBSInterrogate.Component.Result.CallDetails[0].AddressOfB.Party.LengthOfNumber = 4,
4709 [33].u.CCBSInterrogate.Component.Result.CallDetails[0].AddressOfB.Party.Number =
"1803",
4710 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].CCBSReference = 102,
4711 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].Q931ie.Bc.Length = 2,
4712 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].Q931ie.Bc.Contents =
"LM",
4713 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].AddressOfB.Party.Type = 8,
4714 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].AddressOfB.Party.LengthOfNumber = 4,
4715 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].AddressOfB.Party.Number =
"6229",
4716 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].AddressOfB.Subaddress.Type = 1,
4717 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].AddressOfB.Subaddress.Length = 4,
4718 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].AddressOfB.Subaddress.u.Nsap =
"8592",
4719 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].SubaddressOfA.Type = 1,
4720 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].SubaddressOfA.Length = 4,
4721 [33].u.CCBSInterrogate.Component.Result.CallDetails[1].SubaddressOfA.u.Nsap =
"6492",
4723 [34].Function = Fac_CCNRRequest,
4724 [34].u.CCNRRequest.InvokeID = 512,
4725 [34].u.CCNRRequest.ComponentType = FacComponent_Invoke,
4726 [34].u.CCNRRequest.Component.Invoke.CallLinkageID = 57,
4728 [35].Function = Fac_CCNRRequest,
4729 [35].u.CCNRRequest.InvokeID = 150,
4730 [35].u.CCNRRequest.ComponentType = FacComponent_Result,
4731 [35].u.CCNRRequest.Component.Result.RecallMode = 1,
4732 [35].u.CCNRRequest.Component.Result.CCBSReference = 102,
4734 [36].Function = Fac_CCNRInterrogate,
4735 [36].u.CCNRInterrogate.InvokeID = -129,
4736 [36].u.CCNRInterrogate.ComponentType = FacComponent_Invoke,
4738 [37].Function = Fac_CCNRInterrogate,
4739 [37].u.CCNRInterrogate.InvokeID = -3,
4740 [37].u.CCNRInterrogate.ComponentType = FacComponent_Result,
4741 [37].u.CCNRInterrogate.Component.Result.RecallMode = 1,
4743 [38].Function = Fac_CCBS_T_Call,
4744 [38].u.EctExecute.InvokeID = 41,
4746 [39].Function = Fac_CCBS_T_Suspend,
4747 [39].u.EctExecute.InvokeID = 42,
4749 [40].Function = Fac_CCBS_T_Resume,
4750 [40].u.EctExecute.InvokeID = 43,
4752 [41].Function = Fac_CCBS_T_RemoteUserFree,
4753 [41].u.EctExecute.InvokeID = 44,
4755 [42].Function = Fac_CCBS_T_Available,
4756 [42].u.EctExecute.InvokeID = 45,
4758 [43].Function = Fac_CCBS_T_Request,
4759 [43].u.CCBS_T_Request.InvokeID = 46,
4760 [43].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
4761 [43].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
4762 [43].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
4763 [43].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number =
"6229",
4764 [43].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
4765 [43].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents =
"LM",
4766 [43].u.CCBS_T_Request.Component.Invoke.RetentionSupported = 1,
4767 [43].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent = 1,
4768 [43].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator = 1,
4769 [43].u.CCBS_T_Request.Component.Invoke.Originating.Party.Type = 8,
4770 [43].u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber = 4,
4771 [43].u.CCBS_T_Request.Component.Invoke.Originating.Party.Number =
"9864",
4773 [44].Function = Fac_CCBS_T_Request,
4774 [44].u.CCBS_T_Request.InvokeID = 47,
4775 [44].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
4776 [44].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
4777 [44].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
4778 [44].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number =
"6229",
4779 [44].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
4780 [44].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents =
"LM",
4781 [44].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent = 1,
4782 [44].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator = 1,
4783 [44].u.CCBS_T_Request.Component.Invoke.Originating.Party.Type = 8,
4784 [44].u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber = 4,
4785 [44].u.CCBS_T_Request.Component.Invoke.Originating.Party.Number =
"9864",
4787 [45].Function = Fac_CCBS_T_Request,
4788 [45].u.CCBS_T_Request.InvokeID = 48,
4789 [45].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
4790 [45].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
4791 [45].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
4792 [45].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number =
"6229",
4793 [45].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
4794 [45].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents =
"LM",
4795 [45].u.CCBS_T_Request.Component.Invoke.Originating.Party.Type = 8,
4796 [45].u.CCBS_T_Request.Component.Invoke.Originating.Party.LengthOfNumber = 4,
4797 [45].u.CCBS_T_Request.Component.Invoke.Originating.Party.Number =
"9864",
4799 [46].Function = Fac_CCBS_T_Request,
4800 [46].u.CCBS_T_Request.InvokeID = 49,
4801 [46].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
4802 [46].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
4803 [46].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
4804 [46].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number =
"6229",
4805 [46].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
4806 [46].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents =
"LM",
4807 [46].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent = 1,
4808 [46].u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator = 1,
4810 [47].Function = Fac_CCBS_T_Request,
4811 [47].u.CCBS_T_Request.InvokeID = 50,
4812 [47].u.CCBS_T_Request.ComponentType = FacComponent_Invoke,
4813 [47].u.CCBS_T_Request.Component.Invoke.Destination.Party.Type = 8,
4814 [47].u.CCBS_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
4815 [47].u.CCBS_T_Request.Component.Invoke.Destination.Party.Number =
"6229",
4816 [47].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
4817 [47].u.CCBS_T_Request.Component.Invoke.Q931ie.Bc.Contents =
"LM",
4819 [48].Function = Fac_CCBS_T_Request,
4820 [48].u.CCBS_T_Request.InvokeID = 51,
4821 [48].u.CCBS_T_Request.ComponentType = FacComponent_Result,
4822 [48].u.CCBS_T_Request.Component.Result.RetentionSupported = 1,
4824 [49].Function = Fac_CCNR_T_Request,
4825 [49].u.CCNR_T_Request.InvokeID = 52,
4826 [49].u.CCNR_T_Request.ComponentType = FacComponent_Invoke,
4827 [49].u.CCNR_T_Request.Component.Invoke.Destination.Party.Type = 8,
4828 [49].u.CCNR_T_Request.Component.Invoke.Destination.Party.LengthOfNumber = 4,
4829 [49].u.CCNR_T_Request.Component.Invoke.Destination.Party.Number =
"6229",
4830 [49].u.CCNR_T_Request.Component.Invoke.Q931ie.Bc.Length = 2,
4831 [49].u.CCNR_T_Request.Component.Invoke.Q931ie.Bc.Contents =
"LM",
4833 [50].Function = Fac_CCNR_T_Request,
4834 [50].u.CCNR_T_Request.InvokeID = 53,
4835 [50].u.CCNR_T_Request.ComponentType = FacComponent_Result,
4836 [50].u.CCNR_T_Request.Component.Result.RetentionSupported = 1,
4838 [51].Function = Fac_EctExecute,
4839 [51].u.EctExecute.InvokeID = 54,
4841 [52].Function = Fac_ExplicitEctExecute,
4842 [52].u.ExplicitEctExecute.InvokeID = 55,
4843 [52].u.ExplicitEctExecute.LinkID = 23,
4845 [53].Function = Fac_RequestSubaddress,
4846 [53].u.RequestSubaddress.InvokeID = 56,
4848 [54].Function = Fac_SubaddressTransfer,
4849 [54].u.SubaddressTransfer.InvokeID = 57,
4850 [54].u.SubaddressTransfer.Subaddress.Type = 1,
4851 [54].u.SubaddressTransfer.Subaddress.Length = 4,
4852 [54].u.SubaddressTransfer.Subaddress.u.Nsap =
"6492",
4854 [55].Function = Fac_EctLinkIdRequest,
4855 [55].u.EctLinkIdRequest.InvokeID = 58,
4856 [55].u.EctLinkIdRequest.ComponentType = FacComponent_Invoke,
4858 [56].Function = Fac_EctLinkIdRequest,
4859 [56].u.EctLinkIdRequest.InvokeID = 59,
4860 [56].u.EctLinkIdRequest.ComponentType = FacComponent_Result,
4861 [56].u.EctLinkIdRequest.Component.Result.LinkID = 76,
4863 [57].Function = Fac_EctInform,
4864 [57].u.EctInform.InvokeID = 60,
4865 [57].u.EctInform.Status = 1,
4866 [57].u.EctInform.RedirectionPresent = 1,
4867 [57].u.EctInform.Redirection.Type = 0,
4868 [57].u.EctInform.Redirection.Unscreened.Type = 8,
4869 [57].u.EctInform.Redirection.Unscreened.LengthOfNumber = 4,
4870 [57].u.EctInform.Redirection.Unscreened.Number =
"6229",
4872 [58].Function = Fac_EctInform,
4873 [58].u.EctInform.InvokeID = 61,
4874 [58].u.EctInform.Status = 1,
4875 [58].u.EctInform.RedirectionPresent = 1,
4876 [58].u.EctInform.Redirection.Type = 1,
4878 [59].Function = Fac_EctInform,
4879 [59].u.EctInform.InvokeID = 62,
4880 [59].u.EctInform.Status = 1,
4881 [59].u.EctInform.RedirectionPresent = 1,
4882 [59].u.EctInform.Redirection.Type = 2,
4884 [60].Function = Fac_EctInform,
4885 [60].u.EctInform.InvokeID = 63,
4886 [60].u.EctInform.Status = 1,
4887 [60].u.EctInform.RedirectionPresent = 1,
4888 [60].u.EctInform.Redirection.Type = 3,
4889 [60].u.EctInform.Redirection.Unscreened.Type = 8,
4890 [60].u.EctInform.Redirection.Unscreened.LengthOfNumber = 4,
4891 [60].u.EctInform.Redirection.Unscreened.Number =
"3340",
4893 [61].Function = Fac_EctInform,
4894 [61].u.EctInform.InvokeID = 64,
4895 [61].u.EctInform.Status = 1,
4896 [61].u.EctInform.RedirectionPresent = 0,
4898 [62].Function = Fac_EctLoopTest,
4899 [62].u.EctLoopTest.InvokeID = 65,
4900 [62].u.EctLoopTest.ComponentType = FacComponent_Invoke,
4901 [62].u.EctLoopTest.Component.Invoke.CallTransferID = 7,
4903 [63].Function = Fac_EctLoopTest,
4904 [63].u.EctLoopTest.InvokeID = 66,
4905 [63].u.EctLoopTest.ComponentType = FacComponent_Result,
4906 [63].u.EctLoopTest.Component.Result.LoopResult = 2,
4908 [64].Function = Fac_ActivationDiversion,
4909 [64].u.ActivationDiversion.InvokeID = 67,
4910 [64].u.ActivationDiversion.ComponentType = FacComponent_Invoke,
4911 [64].u.ActivationDiversion.Component.Invoke.Procedure = 2,
4912 [64].u.ActivationDiversion.Component.Invoke.BasicService = 3,
4913 [64].u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Type = 4,
4914 [64].u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.LengthOfNumber = 4,
4915 [64].u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number =
"1803",
4916 [64].u.ActivationDiversion.Component.Invoke.ServedUser.Type = 4,
4917 [64].u.ActivationDiversion.Component.Invoke.ServedUser.LengthOfNumber = 4,
4918 [64].u.ActivationDiversion.Component.Invoke.ServedUser.Number =
"5398",
4920 [65].Function = Fac_ActivationDiversion,
4921 [65].u.ActivationDiversion.InvokeID = 68,
4922 [65].u.ActivationDiversion.ComponentType = FacComponent_Invoke,
4923 [65].u.ActivationDiversion.Component.Invoke.Procedure = 1,
4924 [65].u.ActivationDiversion.Component.Invoke.BasicService = 5,
4925 [65].u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Type = 4,
4926 [65].u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.LengthOfNumber = 4,
4927 [65].u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number =
"1803",
4929 [66].Function = Fac_ActivationDiversion,
4930 [66].u.ActivationDiversion.InvokeID = 69,
4931 [66].u.ActivationDiversion.ComponentType = FacComponent_Result,
4933 [67].Function = Fac_DeactivationDiversion,
4934 [67].u.DeactivationDiversion.InvokeID = 70,
4935 [67].u.DeactivationDiversion.ComponentType = FacComponent_Invoke,
4936 [67].u.DeactivationDiversion.Component.Invoke.Procedure = 1,
4937 [67].u.DeactivationDiversion.Component.Invoke.BasicService = 5,
4939 [68].Function = Fac_DeactivationDiversion,
4940 [68].u.DeactivationDiversion.InvokeID = 71,
4941 [68].u.DeactivationDiversion.ComponentType = FacComponent_Result,
4943 [69].Function = Fac_ActivationStatusNotificationDiv,
4944 [69].u.ActivationStatusNotificationDiv.InvokeID = 72,
4945 [69].u.ActivationStatusNotificationDiv.Procedure = 1,
4946 [69].u.ActivationStatusNotificationDiv.BasicService = 5,
4947 [69].u.ActivationStatusNotificationDiv.ForwardedTo.Party.Type = 4,
4948 [69].u.ActivationStatusNotificationDiv.ForwardedTo.Party.LengthOfNumber = 4,
4949 [69].u.ActivationStatusNotificationDiv.ForwardedTo.Party.Number =
"1803",
4951 [70].Function = Fac_DeactivationStatusNotificationDiv,
4952 [70].u.DeactivationStatusNotificationDiv.InvokeID = 73,
4953 [70].u.DeactivationStatusNotificationDiv.Procedure = 1,
4954 [70].u.DeactivationStatusNotificationDiv.BasicService = 5,
4956 [71].Function = Fac_InterrogationDiversion,
4957 [71].u.InterrogationDiversion.InvokeID = 74,
4958 [71].u.InterrogationDiversion.ComponentType = FacComponent_Invoke,
4959 [71].u.InterrogationDiversion.Component.Invoke.Procedure = 1,
4960 [71].u.InterrogationDiversion.Component.Invoke.BasicService = 5,
4962 [72].Function = Fac_InterrogationDiversion,
4963 [72].u.InterrogationDiversion.InvokeID = 75,
4964 [72].u.InterrogationDiversion.ComponentType = FacComponent_Invoke,
4965 [72].u.InterrogationDiversion.Component.Invoke.Procedure = 1,
4967 [73].Function = Fac_InterrogationDiversion,
4968 [73].u.InterrogationDiversion.InvokeID = 76,
4969 [73].u.InterrogationDiversion.ComponentType = FacComponent_Result,
4970 [73].u.InterrogationDiversion.Component.Result.NumRecords = 2,
4971 [73].u.InterrogationDiversion.Component.Result.List[0].Procedure = 2,
4972 [73].u.InterrogationDiversion.Component.Result.List[0].BasicService = 5,
4973 [73].u.InterrogationDiversion.Component.Result.List[0].ForwardedTo.Party.Type = 4,
4974 [73].u.InterrogationDiversion.Component.Result.List[0].ForwardedTo.Party.LengthOfNumber = 4,
4975 [73].u.InterrogationDiversion.Component.Result.List[0].ForwardedTo.Party.Number =
"1803",
4976 [73].u.InterrogationDiversion.Component.Result.List[1].Procedure = 1,
4977 [73].u.InterrogationDiversion.Component.Result.List[1].BasicService = 3,
4978 [73].u.InterrogationDiversion.Component.Result.List[1].ForwardedTo.Party.Type = 4,
4979 [73].u.InterrogationDiversion.Component.Result.List[1].ForwardedTo.Party.LengthOfNumber = 4,
4980 [73].u.InterrogationDiversion.Component.Result.List[1].ForwardedTo.Party.Number =
"1903",
4981 [73].u.InterrogationDiversion.Component.Result.List[1].ServedUser.Type = 4,
4982 [73].u.InterrogationDiversion.Component.Result.List[1].ServedUser.LengthOfNumber = 4,
4983 [73].u.InterrogationDiversion.Component.Result.List[1].ServedUser.Number =
"5398",
4985 [74].Function = Fac_DiversionInformation,
4986 [74].u.DiversionInformation.InvokeID = 77,
4987 [74].u.DiversionInformation.DiversionReason = 3,
4988 [74].u.DiversionInformation.BasicService = 5,
4989 [74].u.DiversionInformation.ServedUserSubaddress.Type = 1,
4990 [74].u.DiversionInformation.ServedUserSubaddress.Length = 4,
4991 [74].u.DiversionInformation.ServedUserSubaddress.u.Nsap =
"6492",
4992 [74].u.DiversionInformation.CallingAddressPresent = 1,
4993 [74].u.DiversionInformation.CallingAddress.Type = 0,
4994 [74].u.DiversionInformation.CallingAddress.Address.ScreeningIndicator = 3,
4995 [74].u.DiversionInformation.CallingAddress.Address.Party.Type = 4,
4996 [74].u.DiversionInformation.CallingAddress.Address.Party.LengthOfNumber = 4,
4997 [74].u.DiversionInformation.CallingAddress.Address.Party.Number =
"1803",
4998 [74].u.DiversionInformation.OriginalCalledPresent = 1,
4999 [74].u.DiversionInformation.OriginalCalled.Type = 1,
5000 [74].u.DiversionInformation.LastDivertingPresent = 1,
5001 [74].u.DiversionInformation.LastDiverting.Type = 2,
5002 [74].u.DiversionInformation.LastDivertingReasonPresent = 1,
5003 [74].u.DiversionInformation.LastDivertingReason = 3,
5004 [74].u.DiversionInformation.UserInfo.Length = 5,
5005 [74].u.DiversionInformation.UserInfo.Contents =
"79828",
5007 [75].Function = Fac_DiversionInformation,
5008 [75].u.DiversionInformation.InvokeID = 78,
5009 [75].u.DiversionInformation.DiversionReason = 3,
5010 [75].u.DiversionInformation.BasicService = 5,
5011 [75].u.DiversionInformation.CallingAddressPresent = 1,
5012 [75].u.DiversionInformation.CallingAddress.Type = 1,
5013 [75].u.DiversionInformation.OriginalCalledPresent = 1,
5014 [75].u.DiversionInformation.OriginalCalled.Type = 2,
5015 [75].u.DiversionInformation.LastDivertingPresent = 1,
5016 [75].u.DiversionInformation.LastDiverting.Type = 1,
5018 [76].Function = Fac_DiversionInformation,
5019 [76].u.DiversionInformation.InvokeID = 79,
5020 [76].u.DiversionInformation.DiversionReason = 2,
5021 [76].u.DiversionInformation.BasicService = 3,
5022 [76].u.DiversionInformation.CallingAddressPresent = 1,
5023 [76].u.DiversionInformation.CallingAddress.Type = 2,
5025 [77].Function = Fac_DiversionInformation,
5026 [77].u.DiversionInformation.InvokeID = 80,
5027 [77].u.DiversionInformation.DiversionReason = 3,
5028 [77].u.DiversionInformation.BasicService = 5,
5029 [77].u.DiversionInformation.CallingAddressPresent = 1,
5030 [77].u.DiversionInformation.CallingAddress.Type = 3,
5031 [77].u.DiversionInformation.CallingAddress.Address.ScreeningIndicator = 2,
5032 [77].u.DiversionInformation.CallingAddress.Address.Party.Type = 4,
5033 [77].u.DiversionInformation.CallingAddress.Address.Party.LengthOfNumber = 4,
5034 [77].u.DiversionInformation.CallingAddress.Address.Party.Number =
"1803",
5036 [78].Function = Fac_DiversionInformation,
5037 [78].u.DiversionInformation.InvokeID = 81,
5038 [78].u.DiversionInformation.DiversionReason = 2,
5039 [78].u.DiversionInformation.BasicService = 4,
5040 [78].u.DiversionInformation.UserInfo.Length = 5,
5041 [78].u.DiversionInformation.UserInfo.Contents =
"79828",
5043 [79].Function = Fac_DiversionInformation,
5044 [79].u.DiversionInformation.InvokeID = 82,
5045 [79].u.DiversionInformation.DiversionReason = 2,
5046 [79].u.DiversionInformation.BasicService = 4,
5048 [80].Function = Fac_CallDeflection,
5049 [80].u.CallDeflection.InvokeID = 83,
5050 [80].u.CallDeflection.ComponentType = FacComponent_Invoke,
5051 [80].u.CallDeflection.Component.Invoke.Deflection.Party.Type = 4,
5052 [80].u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = 4,
5053 [80].u.CallDeflection.Component.Invoke.Deflection.Party.Number =
"1803",
5054 [80].u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1,
5055 [80].u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 1,
5057 [81].Function = Fac_CallDeflection,
5058 [81].u.CallDeflection.InvokeID = 84,
5059 [81].u.CallDeflection.ComponentType = FacComponent_Invoke,
5060 [81].u.CallDeflection.Component.Invoke.Deflection.Party.Type = 4,
5061 [81].u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = 4,
5062 [81].u.CallDeflection.Component.Invoke.Deflection.Party.Number =
"1803",
5063 [81].u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1,
5064 [81].u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 0,
5066 [82].Function = Fac_CallDeflection,
5067 [82].u.CallDeflection.InvokeID = 85,
5068 [82].u.CallDeflection.ComponentType = FacComponent_Invoke,
5069 [82].u.CallDeflection.Component.Invoke.Deflection.Party.Type = 4,
5070 [82].u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = 4,
5071 [82].u.CallDeflection.Component.Invoke.Deflection.Party.Number =
"1803",
5073 [83].Function = Fac_CallDeflection,
5074 [83].u.CallDeflection.InvokeID = 86,
5075 [83].u.CallDeflection.ComponentType = FacComponent_Result,
5077 [84].Function = Fac_CallRerouteing,
5078 [84].u.CallRerouteing.InvokeID = 87,
5079 [84].u.CallRerouteing.ComponentType = FacComponent_Invoke,
5080 [84].u.CallRerouteing.Component.Invoke.ReroutingReason = 3,
5081 [84].u.CallRerouteing.Component.Invoke.ReroutingCounter = 2,
5082 [84].u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 4,
5083 [84].u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = 4,
5084 [84].u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number =
"1803",
5085 [84].u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 2,
5086 [84].u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents =
"RT",
5087 [84].u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Length = 3,
5088 [84].u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Contents =
"RTG",
5089 [84].u.CallRerouteing.Component.Invoke.Q931ie.Llc.Length = 2,
5090 [84].u.CallRerouteing.Component.Invoke.Q931ie.Llc.Contents =
"MY",
5091 [84].u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Length = 5,
5092 [84].u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Contents =
"YEHAW",
5093 [84].u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1,
5094 [84].u.CallRerouteing.Component.Invoke.SubscriptionOption = 2,
5095 [84].u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Type = 1,
5096 [84].u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length = 4,
5097 [84].u.CallRerouteing.Component.Invoke.CallingPartySubaddress.u.Nsap =
"6492",
5099 [85].Function = Fac_CallRerouteing,
5100 [85].u.CallRerouteing.InvokeID = 88,
5101 [85].u.CallRerouteing.ComponentType = FacComponent_Invoke,
5102 [85].u.CallRerouteing.Component.Invoke.ReroutingReason = 3,
5103 [85].u.CallRerouteing.Component.Invoke.ReroutingCounter = 2,
5104 [85].u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 4,
5105 [85].u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = 4,
5106 [85].u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number =
"1803",
5107 [85].u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 2,
5108 [85].u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents =
"RT",
5109 [85].u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1,
5110 [85].u.CallRerouteing.Component.Invoke.SubscriptionOption = 2,
5112 [86].Function = Fac_CallRerouteing,
5113 [86].u.CallRerouteing.InvokeID = 89,
5114 [86].u.CallRerouteing.ComponentType = FacComponent_Invoke,
5115 [86].u.CallRerouteing.Component.Invoke.ReroutingReason = 3,
5116 [86].u.CallRerouteing.Component.Invoke.ReroutingCounter = 2,
5117 [86].u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 4,
5118 [86].u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = 4,
5119 [86].u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number =
"1803",
5120 [86].u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 2,
5121 [86].u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents =
"RT",
5122 [86].u.CallRerouteing.Component.Invoke.LastRerouting.Type = 2,
5124 [87].Function = Fac_CallRerouteing,
5125 [87].u.CallRerouteing.InvokeID = 90,
5126 [87].u.CallRerouteing.ComponentType = FacComponent_Result,
5128 [88].Function = Fac_InterrogateServedUserNumbers,
5129 [88].u.InterrogateServedUserNumbers.InvokeID = 91,
5130 [88].u.InterrogateServedUserNumbers.ComponentType = FacComponent_Invoke,
5132 [89].Function = Fac_InterrogateServedUserNumbers,
5133 [89].u.InterrogateServedUserNumbers.InvokeID = 92,
5134 [89].u.InterrogateServedUserNumbers.ComponentType = FacComponent_Result,
5135 [89].u.InterrogateServedUserNumbers.Component.Result.NumRecords = 2,
5136 [89].u.InterrogateServedUserNumbers.Component.Result.List[0].Type = 4,
5137 [89].u.InterrogateServedUserNumbers.Component.Result.List[0].LengthOfNumber = 4,
5138 [89].u.InterrogateServedUserNumbers.Component.Result.List[0].Number =
"1803",
5139 [89].u.InterrogateServedUserNumbers.Component.Result.List[1].Type = 4,
5140 [89].u.InterrogateServedUserNumbers.Component.Result.List[1].LengthOfNumber = 4,
5141 [89].u.InterrogateServedUserNumbers.Component.Result.List[1].Number =
"5786",
5143 [90].Function = Fac_DivertingLegInformation1,
5144 [90].u.DivertingLegInformation1.InvokeID = 93,
5145 [90].u.DivertingLegInformation1.DiversionReason = 4,
5146 [90].u.DivertingLegInformation1.SubscriptionOption = 1,
5147 [90].u.DivertingLegInformation1.DivertedToPresent = 1,
5148 [90].u.DivertingLegInformation1.DivertedTo.Type = 2,
5150 [91].Function = Fac_DivertingLegInformation1,
5151 [91].u.DivertingLegInformation1.InvokeID = 94,
5152 [91].u.DivertingLegInformation1.DiversionReason = 4,
5153 [91].u.DivertingLegInformation1.SubscriptionOption = 1,
5155 [92].Function = Fac_DivertingLegInformation2,
5156 [92].u.DivertingLegInformation2.InvokeID = 95,
5157 [92].u.DivertingLegInformation2.DiversionCounter = 3,
5158 [92].u.DivertingLegInformation2.DiversionReason = 2,
5159 [92].u.DivertingLegInformation2.DivertingPresent = 1,
5160 [92].u.DivertingLegInformation2.Diverting.Type = 2,
5161 [92].u.DivertingLegInformation2.OriginalCalledPresent = 1,
5162 [92].u.DivertingLegInformation2.OriginalCalled.Type = 1,
5164 [93].Function = Fac_DivertingLegInformation2,
5165 [93].u.DivertingLegInformation2.InvokeID = 96,
5166 [93].u.DivertingLegInformation2.DiversionCounter = 3,
5167 [93].u.DivertingLegInformation2.DiversionReason = 2,
5168 [93].u.DivertingLegInformation2.OriginalCalledPresent = 1,
5169 [93].u.DivertingLegInformation2.OriginalCalled.Type = 1,
5171 [94].Function = Fac_DivertingLegInformation2,
5172 [94].u.DivertingLegInformation2.InvokeID = 97,
5173 [94].u.DivertingLegInformation2.DiversionCounter = 1,
5174 [94].u.DivertingLegInformation2.DiversionReason = 2,
5176 [95].Function = Fac_DivertingLegInformation3,
5177 [95].u.DivertingLegInformation3.InvokeID = 98,
5178 [95].u.DivertingLegInformation3.PresentationAllowedIndicator = 1,
5185 const char *channame;
5189 const char *served_nr;
5195 e->
command =
"misdn send facility";
5196 e->
usage =
"Usage: misdn send facility <type> <channel|port> \"<args>\" \n" 5197 "\t type is one of:\n" 5198 "\t - calldeflect\n" 5199 #if defined(AST_MISDN_ENHANCEMENTS) 5200 "\t - callrerouting\n" 5203 "\t - CFDeactivate\n";
5214 if (strstr(a->
argv[3],
"calldeflect")) {
5216 ast_verbose(
"calldeflect requires 1 arg: ToNumber\n\n");
5219 channame = a->
argv[4];
5222 ast_verbose(
"Sending Calldeflection (%s) to %s\n", nr, channame);
5225 ast_verbose(
"Sending CD with nr %s to %s failed: Channel does not exist.\n", nr, channame);
5230 #if defined(AST_MISDN_ENHANCEMENTS) 5231 max_len =
sizeof(tmp->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number) - 1;
5232 if (max_len < strlen(nr)) {
5233 ast_verbose(
"Sending CD with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
5234 nr, channame, max_len);
5239 tmp->
bc->
fac_out.Function = Fac_CallDeflection;
5240 tmp->
bc->
fac_out.u.CallDeflection.InvokeID = ++misdn_invoke_id;
5241 tmp->
bc->
fac_out.u.CallDeflection.ComponentType = FacComponent_Invoke;
5242 tmp->
bc->
fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1;
5243 tmp->
bc->
fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 0;
5244 tmp->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Type = 0;
5245 tmp->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = strlen(nr);
5246 strcpy((
char *) tmp->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number, nr);
5247 tmp->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Subaddress.Length = 0;
5251 max_len =
sizeof(tmp->
bc->
fac_out.u.CDeflection.DeflectedToNumber) - 1;
5252 if (max_len < strlen(nr)) {
5253 ast_verbose(
"Sending CD with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
5254 nr, channame, max_len);
5260 tmp->
bc->
fac_out.u.CDeflection.PresentationAllowed = 0;
5262 strcpy((
char *) tmp->
bc->
fac_out.u.CDeflection.DeflectedToNumber, nr);
5270 #if defined(AST_MISDN_ENHANCEMENTS) 5271 }
else if (strstr(a->
argv[3],
"callrerouteing") || strstr(a->
argv[3],
"callrerouting")) {
5273 ast_verbose(
"callrerouting requires 1 arg: ToNumber\n\n");
5276 channame = a->
argv[4];
5279 ast_verbose(
"Sending Callrerouting (%s) to %s\n", nr, channame);
5282 ast_verbose(
"Sending Call Rerouting with nr %s to %s failed: Channel does not exist.\n", nr, channame);
5287 max_len =
sizeof(tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number) - 1;
5288 if (max_len < strlen(nr)) {
5289 ast_verbose(
"Sending Call Rerouting with nr %s to %s failed: Number too long (up to %u digits are allowed).\n",
5290 nr, channame, max_len);
5295 tmp->
bc->
fac_out.Function = Fac_CallRerouteing;
5296 tmp->
bc->
fac_out.u.CallRerouteing.InvokeID = ++misdn_invoke_id;
5297 tmp->
bc->
fac_out.u.CallRerouteing.ComponentType = FacComponent_Invoke;
5299 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.ReroutingReason = 0;
5300 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.ReroutingCounter = 1;
5302 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 0;
5303 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = strlen(nr);
5304 strcpy((
char *) tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number, nr);
5305 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Subaddress.Length = 0;
5307 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length = 0;
5310 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 3;
5311 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[0] = 0x90;
5312 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[1] = 0x90;
5313 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[2] = 0xa3;
5314 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Length = 0;
5315 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Llc.Length = 0;
5316 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Length = 0;
5318 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1;
5319 tmp->
bc->
fac_out.u.CallRerouteing.Component.Invoke.SubscriptionOption = 0;
5327 }
else if (strstr(a->
argv[3],
"CFActivate")) {
5329 ast_verbose(
"CFActivate requires 2 args: 1.FromNumber, 2.ToNumber\n\n");
5332 port = atoi(a->
argv[4]);
5333 served_nr = a->
argv[5];
5338 ast_verbose(
"Sending CFActivate Port:(%d) FromNr. (%s) to Nr. (%s)\n", port, served_nr, nr);
5340 #if defined(AST_MISDN_ENHANCEMENTS) 5341 bc->
fac_out.Function = Fac_ActivationDiversion;
5342 bc->
fac_out.u.ActivationDiversion.InvokeID = ++misdn_invoke_id;
5343 bc->
fac_out.u.ActivationDiversion.ComponentType = FacComponent_Invoke;
5344 bc->
fac_out.u.ActivationDiversion.Component.Invoke.BasicService = 0;
5345 bc->
fac_out.u.ActivationDiversion.Component.Invoke.Procedure = 0;
5347 served_nr,
sizeof(bc->
fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number));
5348 bc->
fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.LengthOfNumber =
5349 strlen((
char *) bc->
fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Number);
5350 bc->
fac_out.u.ActivationDiversion.Component.Invoke.ServedUser.Type = 0;
5352 nr,
sizeof(bc->
fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number));
5353 bc->
fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.LengthOfNumber =
5354 strlen((
char *) bc->
fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Number);
5355 bc->
fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Party.Type = 0;
5356 bc->
fac_out.u.ActivationDiversion.Component.Invoke.ForwardedTo.Subaddress.Length = 0;
5360 bc->
fac_out.Function = Fac_CFActivate;
5361 bc->
fac_out.u.CFActivate.BasicService = 0;
5362 bc->
fac_out.u.CFActivate.Procedure = 0;
5370 }
else if (strstr(a->
argv[3],
"CFDeactivate")) {
5372 ast_verbose(
"CFDeactivate requires 1 arg: FromNumber\n\n");
5375 port = atoi(a->
argv[4]);
5376 served_nr = a->
argv[5];
5379 ast_verbose(
"Sending CFDeactivate Port:(%d) FromNr. (%s)\n", port, served_nr);
5381 #if defined(AST_MISDN_ENHANCEMENTS) 5382 bc->
fac_out.Function = Fac_DeactivationDiversion;
5383 bc->
fac_out.u.DeactivationDiversion.InvokeID = ++misdn_invoke_id;
5384 bc->
fac_out.u.DeactivationDiversion.ComponentType = FacComponent_Invoke;
5385 bc->
fac_out.u.DeactivationDiversion.Component.Invoke.BasicService = 0;
5386 bc->
fac_out.u.DeactivationDiversion.Component.Invoke.Procedure = 0;
5388 served_nr,
sizeof(bc->
fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number));
5389 bc->
fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.LengthOfNumber =
5390 strlen((
char *) bc->
fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Number);
5391 bc->
fac_out.u.DeactivationDiversion.Component.Invoke.ServedUser.Type = 0;
5395 bc->
fac_out.Function = Fac_CFDeactivate;
5396 bc->
fac_out.u.CFDeactivate.BasicService = 0;
5397 bc->
fac_out.u.CFDeactivate.Procedure = 0;
5404 #if defined(AST_MISDN_ENHANCEMENTS) && defined(CCBS_TEST_MESSAGES) 5405 }
else if (strstr(a->
argv[3],
"test")) {
5409 ast_verbose(
"test (<port> [<msg#>]) | (<channel-name> <msg#>)\n\n");
5412 port = atoi(a->
argv[4]);
5414 channame = a->
argv[4];
5418 msg_number = atoi(a->
argv[5]);
5421 tmp->
bc->
fac_out = Fac_Msgs[msg_number];
5431 }
else if (a->
argc < 6) {
5432 for (msg_number = 0; msg_number <
ARRAY_LEN(Fac_Msgs); ++msg_number) {
5434 bc->
fac_out = Fac_Msgs[msg_number];
5442 msg_number = atoi(a->
argv[5]);
5445 bc->
fac_out = Fac_Msgs[msg_number];
5454 }
else if (strstr(a->
argv[3],
"register")) {
5459 port = atoi(a->
argv[4]);
5461 bc = misdn_lib_get_register_bc(port);
5463 ast_verbose(
"Could not allocate REGISTER bc struct\n\n");
5484 e->
command =
"misdn send restart";
5486 "Usage: misdn send restart [port [channel]]\n" 5487 " Send a restart for every bchannel on the given port.\n";
5497 port = atoi(a->
argv[3]);
5500 channel = atoi(a->
argv[4]);
5511 const char *channame;
5518 e->
command =
"misdn send digit";
5520 "Usage: misdn send digit <channel> \"<msg>\" \n" 5521 " Send <digit> to <channel> as DTMF Tone\n" 5522 " when channel is a mISDN channel\n";
5532 channame = a->
argv[3];
5534 msglen = strlen(msg);
5536 ast_cli(a->
fd,
"Sending %s to %s\n", msg, channame);
5540 ast_cli(a->
fd,
"Sending %s to %s failed Channel does not exist\n", msg, channame);
5544 for (i = 0; i < msglen; i++) {
5548 ast_cli(a->
fd,
"Sending: %c\n", msg[i]);
5566 const char *channame;
5571 e->
command =
"misdn toggle echocancel";
5573 "Usage: misdn toggle echocancel <channel>\n" 5574 " Toggle EchoCancel on mISDN Channel.\n";
5584 channame = a->
argv[3];
5586 ast_cli(a->
fd,
"Toggling EchoCancel on %s\n", channame);
5590 ast_cli(a->
fd,
"Toggling EchoCancel %s failed Channel does not exist\n", channame);
5598 update_pipeline_config(tmp->
bc);
5613 const char *channame;
5619 e->
command =
"misdn send display";
5621 "Usage: misdn send display <channel> \"<msg>\" \n" 5622 " Send <msg> to <channel> as Display Message\n" 5623 " when channel is a mISDN channel\n";
5633 channame = a->
argv[3];
5636 ast_cli(a->
fd,
"Sending %s to %s\n", msg, channame);
5639 if (tmp && tmp->
bc) {
5647 ast_cli(a->
fd,
"No such channel %s\n", channame);
5667 if (a->
word[0] ==
'p') {
5669 }
else if (a->
word[0] ==
'o') {
5674 if (a->
word[0] ==
'o') {
5686 int wordlen = strlen(a->
word);
5692 if ((!strncmp(a->
word,
"description", wordlen)) && (++which > a->
n)) {
5695 if ((!strncmp(a->
word,
"descriptions", wordlen)) && (++which > a->
n)) {
5698 if ((!strncmp(a->
word,
"0", wordlen)) && (++which > a->
n)) {
5702 snprintf(buffer,
sizeof(buffer),
"%d", port);
5703 if ((!strncmp(a->
word, buffer, wordlen)) && (++which > a->
n)) {
5709 if (strstr(a->
line,
"description ")) {
5715 if (!wordlen || !strncmp(a->
word, buffer, wordlen)) {
5716 if (++which > a->
n) {
5721 }
else if (strstr(a->
line,
"descriptions ")) {
5722 if ((!wordlen || !strncmp(a->
word,
"general", wordlen)) && (++which > a->
n)) {
5725 if ((!wordlen || !strncmp(a->
word,
"ports", wordlen)) && (++which > a->
n)) {
5777 if (! ast || ! bc) {
5800 chan_misdn_log(2, port,
" --> pres: %d screen: %d\n", pres, screen);
5802 if (pres < 0 || screen < 0) {
5829 if (len <= 100 || len > 8000) {
5830 chan_misdn_log(0, bc->
port,
"config_jb: Jitterbuffer out of Bounds, setting to 1000\n");
5834 if (threshold > len) {
5835 chan_misdn_log(0, bc->
port,
"config_jb: Jitterbuffer Threshold > Jitterbuffer setting to Jitterbuffer -1\n");
5839 cb_log(0, bc->
port,
"config_jb: We've got a Jitterbuffer Already on this port.\n");
5876 chan_misdn_log(0, port,
" --> !!!! Wrong dialplan setting, please see the misdn.conf sample file\n ");
5887 misdn_cfg_get(bc->
port, MISDN_CFG_PIPELINE, bc->pipeline,
sizeof(bc->pipeline));
5889 if (*bc->pipeline) {
5896 }
else if (ec > 1) {
5897 snprintf(bc->pipeline,
sizeof(bc->pipeline),
"mg2ec(deftaps=%d)", ec);
5906 int port = bc->
port;
5912 }
else if (ec > 1) {
5934 struct ast_namedgroups *npg;
5935 struct ast_namedgroups *ncg;
5945 if (! ast || ! bc) {
5955 ast_channel_language_set(ast, lang);
6007 update_pipeline_config(bc);
6049 if (strstr(faxdetect,
"outgoing") || strstr(faxdetect,
"both")) {
6050 ch->
faxdetect = strstr(faxdetect,
"nojump") ? 2 : 1;
6080 if (strstr(faxdetect,
"incoming") || strstr(faxdetect,
"both")) {
6081 ch->
faxdetect = (strstr(faxdetect,
"nojump")) ? 2 : 1;
6141 memset(&update_connected, 0,
sizeof(update_connected));
6156 connected.
id.
tag = cid_tag;
6157 connected.
source = source;
6176 memset(&update_caller, 0,
sizeof(update_caller));
6192 caller.
id.
tag = cid_tag;
6193 caller.
ani.
tag = cid_tag;
6253 if (0 <= number_type) {
6281 if (0 <= number_type) {
6342 #if defined(AST_MISDN_ENHANCEMENTS) 6347 bc->
fac_out.Function = Fac_RequestSubaddress;
6348 bc->
fac_out.u.RequestSubaddress.InvokeID = ++misdn_invoke_id;
6355 #if defined(AST_MISDN_ENHANCEMENTS) 6358 bc->
fac_out.Function = Fac_EctInform;
6359 bc->
fac_out.u.EctInform.InvokeID = ++misdn_invoke_id;
6360 bc->
fac_out.u.EctInform.Status = 1;
6361 bc->
fac_out.u.EctInform.RedirectionPresent = 1;
6362 misdn_PresentedNumberUnscreened_fill(&bc->
fac_out.u.EctInform.Redirection,
6443 memset(&update_redirecting, 0,
sizeof(update_redirecting));
6465 redirecting.
to.
tag = tag;
6518 #if defined(AST_MISDN_ENHANCEMENTS) 6523 if (!bc->div_leg_3_tx_pending
6526 bc->
fac_out.Function = Fac_DivertingLegInformation1;
6527 bc->
fac_out.u.DivertingLegInformation1.InvokeID = ++misdn_invoke_id;
6528 bc->
fac_out.u.DivertingLegInformation1.DiversionReason =
6530 bc->
fac_out.u.DivertingLegInformation1.SubscriptionOption = 2;
6531 bc->
fac_out.u.DivertingLegInformation1.DivertedToPresent = 1;
6532 misdn_PresentedNumberUnscreened_fill(&bc->
fac_out.u.DivertingLegInformation1.DivertedTo, &bc->
redirecting.
to);
6536 bc->div_leg_3_tx_pending = 0;
6539 bc->
fac_out.Function = Fac_DivertingLegInformation3;
6540 bc->
fac_out.u.DivertingLegInformation3.InvokeID = ++misdn_invoke_id;
6541 bc->
fac_out.u.DivertingLegInformation3.PresentationAllowedIndicator =
6572 ast_log(
LOG_WARNING,
" --> ! misdn_call called on ast_channel *ast where ast == NULL\n");
6601 #if defined(AST_MISDN_ENHANCEMENTS) 6602 if ((ch->peer = misdn_cc_caller_get(ast))) {
6604 ch->peer->chan ?
"available" :
"NULL");
6607 if (ch->record_id != -1) {
6608 struct misdn_cc_record *cc_record;
6612 cc_record = misdn_cc_find_by_id(ch->record_id);
6622 newbc->
dialed = cc_record->redial.dialed;
6623 newbc->
caller = cc_record->redial.caller;
6625 newbc->
capability = cc_record->redial.capability;
6626 newbc->
hdlc = cc_record->redial.hdlc;
6629 if (cc_record->ptp) {
6630 newbc->
fac_out.Function = Fac_CCBS_T_Call;
6631 newbc->
fac_out.u.CCBS_T_Call.InvokeID = ++misdn_invoke_id;
6633 newbc->
fac_out.Function = Fac_CCBSCall;
6634 newbc->
fac_out.u.CCBSCall.InvokeID = ++misdn_invoke_id;
6635 newbc->
fac_out.u.CCBSCall.CCBSReference = cc_record->mode.ptmp.reference_id;
6690 if (number_type < 0) {
6736 #if defined(AST_MISDN_ENHANCEMENTS) 6743 newbc->
fac_out.Function = Fac_DivertingLegInformation2;
6744 newbc->
fac_out.u.DivertingLegInformation2.InvokeID = ++misdn_invoke_id;
6745 newbc->
fac_out.u.DivertingLegInformation2.DivertingPresent = 1;
6746 misdn_PresentedNumberUnscreened_fill(
6747 &newbc->
fac_out.u.DivertingLegInformation2.Diverting,
6752 newbc->
fac_out.u.DivertingLegInformation2.Diverting.Type = 1;
6755 newbc->
fac_out.u.DivertingLegInformation2.DiversionCounter = 1;
6756 newbc->
fac_out.u.DivertingLegInformation2.DiversionReason = 0;
6759 newbc->
fac_out.u.DivertingLegInformation2.DiversionCounter =
6761 newbc->
fac_out.u.DivertingLegInformation2.DiversionReason =
6765 newbc->
fac_out.u.DivertingLegInformation2.OriginalCalledPresent = 0;
6766 if (1 < newbc->
fac_out.u.DivertingLegInformation2.DiversionCounter) {
6767 newbc->
fac_out.u.DivertingLegInformation2.OriginalCalledPresent = 1;
6768 newbc->
fac_out.u.DivertingLegInformation2.OriginalCalled.Type = 2;
6775 newbc->div_leg_3_rx_wanted = 1;
6784 snprintf(tmp,
sizeof(tmp),
"%d", exceed);
6791 #if defined(AST_MISDN_ENHANCEMENTS) 6792 if (newbc->
fac_out.Function != Fac_None) {
6802 chan_misdn_log(0, port,
" --> * Theres no Channel at the moment .. !\n");
6803 chan_misdn_log(1, port,
" --> * SEND: State Down pid:%d\n", newbc ? newbc->
pid : -1);
6809 chan_misdn_log(2, port,
" --> * SEND: State Dialing pid:%d\n", newbc ? newbc->
pid : 1);
6841 chan_misdn_log(1, 0,
" --> Got Answer, but there is no bc obj ??\n");
6891 #if defined(AST_MISDN_ENHANCEMENTS) 6892 if (p->
bc->div_leg_3_tx_pending) {
6893 p->
bc->div_leg_3_tx_pending = 0;
6896 p->
bc->
fac_out.Function = Fac_DivertingLegInformation3;
6897 p->
bc->
fac_out.u.DivertingLegInformation3.InvokeID = ++misdn_invoke_id;
6898 p->
bc->
fac_out.u.DivertingLegInformation3.PresentationAllowedIndicator =
6986 chan_misdn_log(1, 0,
"* IND : Indication [%d] ignored on %s\n", cond,
6990 chan_misdn_log(1, 0,
"* IND : Indication [%d] ignored on hold %s\n",
7019 chan_misdn_log(2, p->
bc->
port,
" --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n", p->
bc->
pid);
7161 ast_debug(1,
"State Reserved (or nothing) => chanIsAvail\n");
7199 tmpcause = atoi(var);
7212 "* IND : HANGUP\tpid:%d context:%s dialed:%s caller:\"%s\" <%s> State:%s\n",
7231 ast_log(
LOG_NOTICE,
"release channel, in INCOMING_SETUP state.. no other events happened\n");
7346 *tmp->
bc->pipeline = 0;
7371 ast_debug(1,
"Already in a fax extension, not redirecting\n");
7397 struct pollfd pfd = { .fd = -1, .events = POLLIN };
7413 pfd.fd = tmp->
pipe[0];
7424 }
else if (pfd.revents & POLLIN) {
7487 chan_misdn_log(7, 0,
"misdn_write: Returning because hold active\n");
7517 if (!strcmp(frame->
src,
"ast_prod")) {
7542 for (i = 0; i <
max; i++) {
7555 "BC not active (nor bridged) dropping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d l3id:%x\n",
7574 cb_log(0, ch->
bc->
port,
"Misdn Jitterbuffer Overflow.\n");
7586 #if defined(mISDN_NATIVE_BRIDGING) 7606 ch1 = get_chan_by_ast(c0);
7610 ch2 = get_chan_by_ast(c1);
7621 if (!p1_b || !p2_b) {
7634 chan_misdn_log(1, ch1->
bc->
port,
"* Making Native Bridge between \"%s\" <%s> and \"%s\" <%s>\n",
7796 #if defined(AST_MISDN_ENHANCEMENTS) 7822 if (-1 < ch->
pipe[0]) {
7825 if (-1 < ch->
pipe[1]) {
7846 #if defined(AST_MISDN_ENHANCEMENTS) 7866 #if defined(AST_MISDN_ENHANCEMENTS) 7867 int cc_retry_call = 0;
7868 long record_id = -1;
7869 struct misdn_cc_record *cc_record;
7870 const char *err_msg;
7880 snprintf(dial_str,
sizeof(dial_str),
"%s/%s", misdn_type, data);
7898 if (
args.intf[0] ==
'g' &&
args.intf[1] ==
':') {
7903 #if defined(AST_MISDN_ENHANCEMENTS) 7904 }
else if (strcmp(
args.intf,
"cc") == 0) {
7907 }
else if ((p = strchr(
args.intf,
':'))) {
7911 port = atoi(
args.intf);
7912 chan_misdn_log(2, port,
" --> Call on preselected Channel (%d).\n", channel);
7914 port = atoi(
args.intf);
7917 ast_log(
LOG_WARNING,
" --> ! IND : Dial(%s) WITHOUT Port or Group, check extensions.conf\n", dial_str);
7921 #if defined(AST_MISDN_ENHANCEMENTS) 7922 if (cc_retry_call) {
7924 ast_log(
LOG_WARNING,
" --> ! IND : Dial(%s) WITHOUT cc-record-id, check extensions.conf\n", dial_str);
7927 if (!isdigit(*
args.ext)) {
7928 ast_log(
LOG_WARNING,
" --> ! IND : Dial(%s) cc-record-id must be a number.\n", dial_str);
7931 record_id = atol(
args.ext);
7934 cc_record = misdn_cc_find_by_id(record_id);
7937 err_msg = misdn_cc_record_not_found;
7941 if (!cc_record->activated) {
7943 err_msg =
"Call completion has not been activated";
7947 port = cc_record->port;
7985 port_start = rr->
port;
7988 if (strcasecmp(cfg_group, group)) {
8002 }
else if (port_up < 0) {
8012 if (wraped && (rr->
port == port_start) && (rr->
channel == bchan_start)) {
8024 if (wraped && (rr->
port == port_start) && (rr->
channel <= bchan_start)) {
8026 }
else if (!newbc || (rr->
channel == maxbchans)) {
8033 }
while (!newbc && (rr->
port > 0));
8040 if (!strcasecmp(cfg_group, group)) {
8062 "Could not Dial out on group '%s'.\n" 8063 "\tEither the L2 and L1 on all of these ports where DOWN (see 'show application misdn_check_l2l1')\n" 8064 "\tOr there was no free channel on none of the ports\n\n",
8071 chan_misdn_log(1, port,
" --> preselected_channel: %d\n", channel);
8075 ast_log(
LOG_WARNING,
"Could not create channel on port:%d for Dial(%s)\n", port, dial_str);
8084 ast_log(
LOG_ERROR,
"Could not create call record for Dial(%s)\n", dial_str);
8093 ast_log(
LOG_ERROR,
"Could not create Asterisk channel for Dial(%s)\n", dial_str);
8097 #if defined(AST_MISDN_ENHANCEMENTS) 8098 cl->record_id = record_id;
8119 if (tmp && tmp->
bc) {
8132 .description =
"Channel driver for mISDN Support (Bri/Pri)",
8152 int chan_offset = 0;
8157 if (tmp_port == port) {
8166 snprintf(newname,
sizeof(newname),
"%s/%d-", misdn_type, chan_offset + c);
8168 snprintf(newname,
sizeof(newname),
"%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++);
8180 int chan_offset = 0;
8190 if (tmp_port == port) {
8203 tmp =
ast_channel_alloc(1, state, cid_num, cid_name,
"", exten,
"", assignedids, requestor, 0,
"%s/%s%d-u%d", misdn_type, c ?
"" :
"tmp", chan_offset + c, glob_channel++);
8205 chan_misdn_log(2, port,
" --> * NEW CHANNEL dialed:%s caller:%s\n", exten, callerid);
8239 if (pipe(chlist->
pipe) < 0) {
8264 for (help = cl_te; help; help = help->
next) {
8265 if (help->
bc == bc) {
8274 "$$$ find_chan_by_bc: No channel found for dialed:%s caller:\"%s\" <%s>\n",
8291 chan_misdn_log(6, bc->
port,
"$$$ find_hold_call: channel:%d dialed:%s caller:\"%s\" <%s>\n",
8297 for (help = cl_te; help; help = help->
next) {
8307 "$$$ find_hold_call: No channel found for dialed:%s caller:\"%s\" <%s>\n",
8322 for (help = cl_te; help; help = help->
next) {
8334 #define TRANSFER_ON_HELD_CALL_HANGUP 1 8335 #if defined(TRANSFER_ON_HELD_CALL_HANGUP) 8356 for (list = cl_te; list; list = list->
next) {
8359 switch (list->
state) {
8391 for (help = cl_te; help->
next; help = help->
next) {
8410 if (cl_te == chan) {
8412 cl_te = cl_te->
next;
8419 for (help = cl_te; help->
next; help = help->
next) {
8420 if (help->
next == chan) {
8449 int port = bc->
port;
8452 cb_log(1, port,
"Cannot hangup chan, no ch\n");
8456 cb_log(5, port,
"hangup_chan called\n");
8459 cb_log(2, port,
" --> hangup\n");
8469 cb_log(2, port,
" --> No need to queue hangup\n");
8477 cb_log(2, port,
" --> queue_hangup\n");
8480 cb_log(1, port,
"Cannot hangup chan, no ast\n");
8525 "* RELEASING CHANNEL pid:%d context:%s dialed:%s caller:\"%s\" <%s>\n",
8543 --misdn_out_calls[bc->
port];
8545 --misdn_in_calls[bc->
port];
8626 switch (active_ch->
state) {
8637 to_target = active_ch->
ast;
8638 to_transferee = held_ch->
ast;
8683 "* Starting Ast context:%s dialed:%s caller:\"%s\" <%s> with 's' extension\n",
8745 switch (bc->
cause) {
8792 if (tmp && (atoi(tmp) == 1)) {
8822 snprintf(tmp,
sizeof(tmp),
"%d", bc->
pid);
8831 snprintf(tmp,
sizeof(tmp),
"%d", bc->
urate);
8849 misdn_in_calls[port]++;
8851 if (max_in_calls >= 0 && max_in_calls < misdn_in_calls[port]) {
8853 return misdn_in_calls[port] - max_in_calls;
8865 if (max_out_calls >= 0 && max_out_calls <= misdn_out_calls[port]) {
8867 return (misdn_out_calls[port] + 1) - max_out_calls;
8870 misdn_out_calls[port]++;
8898 #if defined(AST_MISDN_ENHANCEMENTS) 8908 static void misdn_cc_handle_ccbs_status_request(
int port,
const struct FacParm *facility)
8910 struct misdn_cc_record *cc_record;
8913 switch (facility->u.CCBSStatusRequest.ComponentType) {
8914 case FacComponent_Invoke:
8917 dummy.
fac_out.Function = Fac_CCBSStatusRequest;
8918 dummy.
fac_out.u.CCBSStatusRequest.InvokeID = facility->u.CCBSStatusRequest.InvokeID;
8919 dummy.
fac_out.u.CCBSStatusRequest.ComponentType = FacComponent_Result;
8923 cc_record = misdn_cc_find_by_reference(port, facility->u.CCBSStatusRequest.Component.Invoke.CCBSReference);
8925 dummy.
fac_out.u.CCBSStatusRequest.Component.Result.Free = cc_record->party_a_free;
8928 dummy.
fac_out.u.CCBSStatusRequest.Component.Result.Free = 1;
8938 chan_misdn_log(0, port,
" --> not yet handled: facility type:0x%04X\n", facility->Function);
8944 #if defined(AST_MISDN_ENHANCEMENTS) 8954 static void misdn_cc_pbx_notify(
long record_id,
const struct misdn_cc_notify *notify)
8959 static unsigned short sequence = 0;
8962 snprintf(id_str,
sizeof(id_str),
"%ld", record_id);
8964 notify->exten, notify->context,
NULL, 0,
8965 "mISDN-CC/%ld-%X", record_id, (
unsigned) ++sequence);
8985 #if defined(AST_MISDN_ENHANCEMENTS) 8994 static void misdn_cc_handle_T_remote_user_free(
struct misdn_bchannel *bc)
8996 struct misdn_cc_record *cc_record;
8997 struct misdn_cc_notify notify;
9001 cc_record = misdn_cc_find_by_bc(bc);
9003 if (cc_record->party_a_free) {
9004 notify = cc_record->remote_user_free;
9007 bc->
fac_out.Function = Fac_CCBS_T_Suspend;
9008 bc->
fac_out.u.CCBS_T_Suspend.InvokeID = ++misdn_invoke_id;
9012 notify = cc_record->b_free;
9014 record_id = cc_record->record_id;
9016 if (notify.context[0]) {
9018 misdn_cc_pbx_notify(record_id, ¬ify);
9026 #if defined(AST_MISDN_ENHANCEMENTS) 9036 static void misdn_cc_handle_remote_user_free(
int port,
const struct FacParm *facility)
9038 struct misdn_cc_record *cc_record;
9039 struct misdn_cc_notify notify;
9043 cc_record = misdn_cc_find_by_reference(port, facility->u.CCBSRemoteUserFree.CCBSReference);
9045 notify = cc_record->remote_user_free;
9046 record_id = cc_record->record_id;
9048 misdn_cc_pbx_notify(record_id, ¬ify);
9055 #if defined(AST_MISDN_ENHANCEMENTS) 9065 static void misdn_cc_handle_b_free(
int port,
const struct FacParm *facility)
9067 struct misdn_cc_record *cc_record;
9068 struct misdn_cc_notify notify;
9072 cc_record = misdn_cc_find_by_reference(port, facility->u.CCBSBFree.CCBSReference);
9073 if (cc_record && cc_record->b_free.context[0]) {
9075 notify = cc_record->b_free;
9076 record_id = cc_record->record_id;
9078 misdn_cc_pbx_notify(record_id, ¬ify);
9097 #if defined(AST_MISDN_ENHANCEMENTS) 9098 const char *diagnostic_msg;
9099 struct misdn_cc_record *cc_record;
9106 switch (bc->
fac_in.Function) {
9107 #if defined(AST_MISDN_ENHANCEMENTS) 9108 case Fac_ActivationDiversion:
9109 switch (bc->
fac_in.u.ActivationDiversion.ComponentType) {
9110 case FacComponent_Result:
9120 case Fac_DeactivationDiversion:
9121 switch (bc->
fac_in.u.DeactivationDiversion.ComponentType) {
9122 case FacComponent_Result:
9132 case Fac_ActivationStatusNotificationDiv:
9137 case Fac_DeactivationStatusNotificationDiv:
9142 case Fac_InterrogationDiversion:
9145 case Fac_InterrogateServedUserNumbers:
9149 case Fac_DiversionInformation:
9153 case Fac_CallDeflection:
9154 if (ch && ch->
ast) {
9155 switch (bc->
fac_in.u.CallDeflection.ComponentType) {
9156 case FacComponent_Invoke:
9163 if (bc->
fac_in.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent) {
9165 bc->
fac_in.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser
9172 memset(&party_id, 0,
sizeof(party_id));
9173 misdn_PartyNumber_extract(&party_id,
9174 &bc->
fac_in.u.CallDeflection.Component.Invoke.Deflection.Party);
9193 bc->
fac_out.Function = Fac_RESULT;
9194 bc->
fac_out.u.RESULT.InvokeID = bc->
fac_in.u.CallDeflection.InvokeID;
9196 bc->
fac_out.Function = Fac_CallDeflection;
9197 bc->
fac_out.u.CallDeflection.InvokeID = bc->
fac_in.u.CallDeflection.InvokeID;
9198 bc->
fac_out.u.CallDeflection.ComponentType = FacComponent_Result;
9207 case FacComponent_Result:
9223 case Fac_CallRerouteing:
9228 case Fac_DivertingLegInformation1:
9230 bc->div_leg_3_rx_wanted = 0;
9231 if (ch && ch->
ast) {
9233 diversion_reason_to_misdn(bc->
fac_in.u.DivertingLegInformation1.DiversionReason);
9234 if (bc->
fac_in.u.DivertingLegInformation1.DivertedToPresent) {
9235 misdn_PresentedNumberUnscreened_extract(&bc->
redirecting.
to,
9236 &bc->
fac_in.u.DivertingLegInformation1.DivertedTo);
9249 bc->div_leg_3_rx_wanted = 1;
9252 case Fac_DivertingLegInformation2:
9257 bc->div_leg_3_tx_pending = 1;
9258 if (ch && ch->
ast) {
9277 diversion_reason_to_misdn(bc->
fac_in.u.DivertingLegInformation2.DiversionReason);
9279 if (bc->
fac_in.u.DivertingLegInformation2.DivertingPresent) {
9282 &bc->
fac_in.u.DivertingLegInformation2.Diverting);
9289 if (bc->
fac_in.u.DivertingLegInformation2.OriginalCalledPresent) {
9297 chan_misdn_log(0, bc->
port,
" --> Expected in a SETUP message: facility type:0x%04X\n",
9302 case Fac_DivertingLegInformation3:
9304 if (bc->div_leg_3_rx_wanted) {
9305 bc->div_leg_3_rx_wanted = 0;
9307 if (ch && ch->
ast) {
9311 bc->
fac_in.u.DivertingLegInformation3.PresentationAllowedIndicator
9334 if (ch && ch->
ast) {
9342 bc->
fac_in.u.CDeflection.PresentationAllowed
9346 (
char *) bc->
fac_in.u.CDeflection.DeflectedToNumber,
9367 case Fac_AOCDCurrency:
9368 if (ch && ch->
ast) {
9375 case Fac_AOCDChargingUnit:
9376 if (ch && ch->
ast) {
9377 bc->
AOCDtype = Fac_AOCDChargingUnit;
9383 #if defined(AST_MISDN_ENHANCEMENTS) 9385 diagnostic_msg = misdn_to_str_error_code(bc->
fac_in.u.ERROR.errorValue);
9392 if (ch && ch->peer) {
9393 misdn_cc_set_peer_var(ch->peer, MISDN_ERROR_MSG, diagnostic_msg);
9400 cc_record = misdn_cc_find_by_invoke(bc->
port, bc->
fac_in.u.ERROR.invokeId);
9402 cc_record->outstanding_message = 0;
9403 cc_record->error_code = bc->
fac_in.u.ERROR.errorValue;
9408 diagnostic_msg = misdn_to_str_reject_code(bc->
fac_in.u.REJECT.Code);
9415 if (ch && ch->peer) {
9416 misdn_cc_set_peer_var(ch->peer, MISDN_ERROR_MSG, diagnostic_msg);
9422 if (bc->
fac_in.u.REJECT.InvokeIDPresent) {
9424 cc_record = misdn_cc_find_by_invoke(bc->
port, bc->
fac_in.u.REJECT.InvokeID);
9426 cc_record->outstanding_message = 0;
9427 cc_record->reject_code = bc->
fac_in.u.REJECT.Code;
9434 cc_record = misdn_cc_find_by_invoke(bc->
port, bc->
fac_in.u.RESULT.InvokeID);
9436 cc_record->outstanding_message = 0;
9441 case Fac_EctExecute:
9444 case Fac_ExplicitEctExecute:
9447 case Fac_EctLinkIdRequest:
9451 case Fac_SubaddressTransfer:
9454 case Fac_RequestSubaddress:
9483 if (!ch || !ch->
ast) {
9495 if (!ch || !ch->
ast) {
9511 if (ch && ch->
ast && bc->
fac_in.u.EctInform.RedirectionPresent) {
9513 memset(&party_id, 0,
sizeof(party_id));
9514 misdn_PresentedNumberUnscreened_extract(&party_id,
9515 &bc->
fac_in.u.EctInform.Redirection);
9529 (bc->
fac_in.u.EctInform.Status == 0 )
9536 case Fac_EctLoopTest:
9541 case Fac_CallInfoRetain:
9546 if (ch && ch->peer) {
9548 if (ch->record_id == -1) {
9549 cc_record = misdn_cc_new();
9560 cc_record = misdn_cc_find_by_id(ch->record_id);
9562 if (cc_record->ptp && cc_record->mode.ptp.bc) {
9571 cc_record->mode.ptp.bc->fac_out.Function = Fac_None;
9580 new_record_id = misdn_cc_record_id_new();
9581 if (new_record_id < 0) {
9584 cc_record->record_id = new_record_id;
9585 ch->record_id = new_record_id;
9588 cc_record->port = bc->
port;
9589 memset(&cc_record->mode, 0,
sizeof(cc_record->mode));
9590 cc_record->mode.ptmp.linkage_id = bc->
fac_in.u.CallInfoRetain.CallLinkageID;
9591 cc_record->invoke_id = ++misdn_invoke_id;
9592 cc_record->activated = 0;
9593 cc_record->outstanding_message = 0;
9594 cc_record->activation_requested = 0;
9595 cc_record->error_code = FacError_None;
9596 cc_record->reject_code = FacReject_None;
9597 memset(&cc_record->remote_user_free, 0,
sizeof(cc_record->remote_user_free));
9598 memset(&cc_record->b_free, 0,
sizeof(cc_record->b_free));
9599 cc_record->time_created = time(
NULL);
9609 cc_record = misdn_cc_new();
9613 ch->record_id = cc_record->record_id;
9615 cc_record->port = bc->
port;
9616 cc_record->mode.ptmp.linkage_id = bc->
fac_in.u.CallInfoRetain.CallLinkageID;
9619 cc_record->redial.caller = bc->
caller;
9620 cc_record->redial.dialed = bc->
dialed;
9621 cc_record->redial.setup_bc_hlc_llc = bc->setup_bc_hlc_llc;
9622 cc_record->redial.capability = bc->
capability;
9623 cc_record->redial.hdlc = bc->
hdlc;
9628 if (ch->record_id != -1) {
9629 snprintf(buf,
sizeof(buf),
"%ld", ch->record_id);
9633 misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, buf);
9638 " --> Expected in a DISCONNECT or ALERTING message: facility type:0x%04X\n",
9643 case Fac_CCBS_T_Call:
9653 chan_misdn_log(0, bc->
port,
" --> Expected in a SETUP message: facility type:0x%04X\n",
9658 case Fac_CCBSDeactivate:
9659 switch (bc->
fac_in.u.CCBSDeactivate.ComponentType) {
9660 case FacComponent_Result:
9662 cc_record = misdn_cc_find_by_invoke(bc->
port, bc->
fac_in.u.CCBSDeactivate.InvokeID);
9664 cc_record->outstanding_message = 0;
9677 cc_record = misdn_cc_find_by_reference(bc->
port, bc->
fac_in.u.CCBSErase.CCBSReference);
9679 misdn_cc_delete(cc_record);
9683 case Fac_CCBSRemoteUserFree:
9684 misdn_cc_handle_remote_user_free(bc->
port, &bc->
fac_in);
9687 misdn_cc_handle_b_free(bc->
port, &bc->
fac_in);
9689 case Fac_CCBSStatusRequest:
9690 misdn_cc_handle_ccbs_status_request(bc->
port, &bc->
fac_in);
9692 case Fac_EraseCallLinkageID:
9694 cc_record = misdn_cc_find_by_linkage(bc->
port,
9695 bc->
fac_in.u.EraseCallLinkageID.CallLinkageID);
9696 if (cc_record && !cc_record->activation_requested) {
9702 misdn_cc_delete(cc_record);
9706 case Fac_CCBSStopAlerting:
9709 case Fac_CCBSRequest:
9710 case Fac_CCNRRequest:
9711 switch (bc->
fac_in.u.CCBSRequest.ComponentType) {
9712 case FacComponent_Result:
9714 cc_record = misdn_cc_find_by_invoke(bc->
port, bc->
fac_in.u.CCBSRequest.InvokeID);
9715 if (cc_record && !cc_record->ptp) {
9716 cc_record->outstanding_message = 0;
9717 cc_record->activated = 1;
9718 cc_record->mode.ptmp.recall_mode = bc->
fac_in.u.CCBSRequest.Component.Result.RecallMode;
9719 cc_record->mode.ptmp.reference_id = bc->
fac_in.u.CCBSRequest.Component.Result.CCBSReference;
9731 case Fac_CCBSInterrogate:
9732 case Fac_CCNRInterrogate:
9735 case Fac_StatusRequest:
9740 case Fac_CCBS_T_Suspend:
9741 case Fac_CCBS_T_Resume:
9745 case Fac_CCBS_T_RemoteUserFree:
9746 misdn_cc_handle_T_remote_user_free(bc);
9748 case Fac_CCBS_T_Available:
9753 if (ch && ch->peer) {
9757 if (ch->record_id == -1) {
9758 cc_record = misdn_cc_new();
9765 cc_record = misdn_cc_find_by_id(ch->record_id);
9767 if (cc_record->ptp && cc_record->mode.ptp.retention_enabled) {
9772 chan_misdn_log(1, bc->
port,
" --> Call-completion request retention option is enabled\n");
9776 if (cc_record->ptp && cc_record->mode.ptp.bc) {
9786 cc_record->mode.ptp.bc->fac_out.Function = Fac_None;
9795 new_record_id = misdn_cc_record_id_new();
9796 if (new_record_id < 0) {
9799 cc_record->record_id = new_record_id;
9800 ch->record_id = new_record_id;
9803 cc_record->port = bc->
port;
9804 memset(&cc_record->mode, 0,
sizeof(cc_record->mode));
9805 cc_record->invoke_id = ++misdn_invoke_id;
9806 cc_record->activated = 0;
9807 cc_record->outstanding_message = 0;
9808 cc_record->activation_requested = 0;
9809 cc_record->error_code = FacError_None;
9810 cc_record->reject_code = FacReject_None;
9811 memset(&cc_record->remote_user_free, 0,
sizeof(cc_record->remote_user_free));
9812 memset(&cc_record->b_free, 0,
sizeof(cc_record->b_free));
9813 cc_record->time_created = time(
NULL);
9823 cc_record = misdn_cc_new();
9827 ch->record_id = cc_record->record_id;
9829 cc_record->port = bc->
port;
9832 cc_record->redial.caller = bc->
caller;
9833 cc_record->redial.dialed = bc->
dialed;
9834 cc_record->redial.setup_bc_hlc_llc = bc->setup_bc_hlc_llc;
9835 cc_record->redial.capability = bc->
capability;
9836 cc_record->redial.hdlc = bc->
hdlc;
9841 if (ch->record_id != -1 && set_id) {
9842 snprintf(buf,
sizeof(buf),
"%ld", ch->record_id);
9846 misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID, buf);
9851 " --> Expected in a DISCONNECT or ALERTING message: facility type:0x%04X\n",
9856 case Fac_CCBS_T_Request:
9857 case Fac_CCNR_T_Request:
9858 switch (bc->
fac_in.u.CCBS_T_Request.ComponentType) {
9859 case FacComponent_Result:
9861 cc_record = misdn_cc_find_by_invoke(bc->
port, bc->
fac_in.u.CCBS_T_Request.InvokeID);
9862 if (cc_record && cc_record->ptp) {
9863 cc_record->outstanding_message = 0;
9864 cc_record->activated = 1;
9865 cc_record->mode.ptp.retention_enabled =
9866 cc_record->mode.ptp.requested_retention
9867 ? bc->
fac_in.u.CCBS_T_Request.Component.Result.RetentionSupported
9874 case FacComponent_Invoke:
9919 #if defined(AST_MISDN_ENHANCEMENTS) 9920 struct misdn_cc_record *cc_record;
9934 "I IND :%s caller:\"%s\" <%s> dialed:%s pid:%d state:%s\n",
9941 if (debuglevel == 1) {
10036 memset(&fr, 0,
sizeof(fr));
10069 const char *pickupexten;
10083 ast_log(
LOG_ERROR,
"Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
10086 pickupexten =
ast_strdupa(pickup_cfg->pickupexten);
10105 "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n",
10115 "Extension '%s@%s' can never match. Disconnecting. port:%d\n" 10116 "\tMaybe you want to add an 'i' extension to catch this case.\n",
10149 memset(&fr, 0,
sizeof(fr));
10177 int append_msn = 0;
10179 const char *pickupexten;
10182 switch (ch->
state) {
10237 ast_log(
LOG_ERROR,
"Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
10240 pickupexten =
ast_strdupa(pickup_cfg->pickupexten);
10246 snprintf(tmp,
sizeof(tmp),
"%d", exceed);
10305 for (i = 0; i <
ARRAY_LEN(allowed_bearers_array); ++i) {
10306 if (allowed_bearers_array[i].cap == bc->
capability) {
10309 if (allowed_bearers_array[i].deprecated) {
10311 allowed_bearers_array[i].
name);
10317 if (i ==
ARRAY_LEN(allowed_bearers_array)) {
10332 if (bc->
fac_in.Function != Fac_None) {
10375 "Extension '%s@%s' can never match. Jumping to 'i' extension. port:%d\n",
10386 "Extension '%s@%s' can never match. Disconnecting. port:%d\n" 10387 "\tMaybe you want to add an 'i' extension to catch this case.\n",
10461 #if defined(AST_MISDN_ENHANCEMENTS) 10463 if (bc->
fac_in.Function != Fac_None) {
10473 bc->
fac_out.Function = Fac_None;
10485 if (bc->
fac_in.Function != Fac_None) {
10511 if (bc->
fac_in.Function != Fac_None) {
10526 if (bc->
fac_in.Function != Fac_None) {
10551 if (bc->
fac_in.Function != Fac_None) {
10560 cb_log(7, bc->
port,
" --> Set State Ringing\n");
10563 cb_log(1, bc->
port,
"Starting Tones, we have inband Data\n");
10566 cb_log(3, bc->
port,
" --> We have no inband Data, the other end must create ringing\n");
10568 cb_log(1, bc->
port,
" --> The other end can not do ringing eh ?.. we must do all ourself..");
10575 if (bc->
fac_in.Function != Fac_None) {
10578 #if defined(AST_MISDN_ENHANCEMENTS) 10579 if (bc->div_leg_3_rx_wanted) {
10580 bc->div_leg_3_rx_wanted = 0;
10613 #if defined(AST_MISDN_ENHANCEMENTS) 10614 if (ch->record_id != -1) {
10622 cc_record = misdn_cc_find_by_id(ch->record_id);
10624 if (cc_record->ptp && cc_record->mode.ptp.bc) {
10626 cc_record->mode.ptp.bc->fac_out.Function = Fac_None;
10630 misdn_cc_delete(cc_record);
10633 ch->record_id = -1;
10635 misdn_cc_set_peer_var(ch->peer, MISDN_CC_RECORD_ID,
"");
10671 if (bc->
fac_in.Function != Fac_None) {
10708 if (bc->
fac_in.Function != Fac_None) {
10715 #if defined(TRANSFER_ON_HELD_CALL_HANGUP) 10745 " --> no Ch, so we've already released. (%s)\n",
10750 if (bc->
fac_in.Function != Fac_None) {
10770 if (bc->
fac_in.Function != Fac_None) {
10778 #if defined(AST_MISDN_ENHANCEMENTS) 10785 cc_record = misdn_cc_find_by_bc(bc);
10788 misdn_cc_delete(cc_record);
10794 " --> no Ch, so we've already released. (%s)\n",
10802 switch (ch->
state) {
10835 if (tone_len < 0 || tone_len > 512) {
10840 res = generate(ast, tmp, tone_len, tone_len);
10859 memset(&frame, 0,
sizeof(frame));
10874 struct pollfd pfd = { .fd = ch->
pipe[1], .events = POLLOUT };
10888 if (pfd.revents & POLLOUT) {
10907 switch (ch->
state) {
10938 chan_misdn_log(1, bc->
port,
" --> in state cleaning .. so ignoring, the stack should clean it for us\n");
10980 if (!hold_allowed) {
11025 if (!ch || !ch->
ast) {
11028 switch (ch->
state) {
11068 if (!ch || !ch->
ast) {
11080 if (!ch || !ch->
ast) {
11095 if (bc->
fac_in.Function == Fac_None) {
11097 chan_misdn_log(0, bc->
port,
" --> Missing facility ie or unknown facility ie contents.\n");
11125 #if defined(AST_MISDN_ENHANCEMENTS) 11139 static int misdn_cc_read(
struct ast_channel *chan,
const char *function_name,
11140 char *function_args,
char *
buf,
size_t size)
11143 struct misdn_cc_record *cc_record;
11167 if (!isdigit(*
args.cc_id)) {
11168 ast_log(
LOG_ERROR,
"Function '%s' call completion record ID must be numeric.\n",
11180 cc_record = misdn_cc_find_by_id(atoi(
args.cc_id));
11182 if (!strcasecmp(
"a-all",
args.get_name)) {
11183 snprintf(buf, size,
"\"%s\" <%s>", cc_record->redial.caller.name,
11184 cc_record->redial.caller.number);
11185 }
else if (!strcasecmp(
"a-name",
args.get_name)) {
11187 }
else if (!strncasecmp(
"a-num",
args.get_name, 5)) {
11189 }
else if (!strcasecmp(
"a-ton",
args.get_name)) {
11190 snprintf(buf, size,
"%d",
11193 }
else if (!strncasecmp(
"a-pres",
args.get_name, 6)) {
11197 }
else if (!strcasecmp(
"a-busy",
args.get_name)) {
11199 }
else if (!strncasecmp(
"b-num",
args.get_name, 5)) {
11201 }
else if (!strcasecmp(
"b-ton",
args.get_name)) {
11202 snprintf(buf, size,
"%d",
11205 }
else if (!strcasecmp(
"port",
args.get_name)) {
11206 snprintf(buf, size,
"%d", cc_record->port);
11207 }
else if (!strcasecmp(
"available-notify-priority",
args.get_name)) {
11208 snprintf(buf, size,
"%d", cc_record->remote_user_free.priority);
11209 }
else if (!strcasecmp(
"available-notify-exten",
args.get_name)) {
11211 }
else if (!strcasecmp(
"available-notify-context",
args.get_name)) {
11213 }
else if (!strcasecmp(
"busy-notify-priority",
args.get_name)) {
11214 snprintf(buf, size,
"%d", cc_record->b_free.priority);
11215 }
else if (!strcasecmp(
"busy-notify-exten",
args.get_name)) {
11217 }
else if (!strcasecmp(
"busy-notify-context",
args.get_name)) {
11221 ast_log(
LOG_ERROR,
"Function '%s': Unknown what-to-get '%s'.\n", function_name,
args.get_name);
11231 #if defined(AST_MISDN_ENHANCEMENTS) 11233 .
name =
"mISDN_CC",
11234 .synopsis =
"Get call completion record information.",
11235 .syntax =
"mISDN_CC(${MISDN_CC_RECORD_ID},<what-to-get>)",
11237 "mISDN_CC(${MISDN_CC_RECORD_ID},<what-to-get>)\n" 11238 "The following can be retrieved:\n" 11239 "\"a-num\", \"a-name\", \"a-all\", \"a-ton\", \"a-pres\", \"a-busy\",\n" 11240 "\"b-num\", \"b-ton\", \"port\",\n" 11241 " User-A is available for call completion:\n" 11242 " \"available-notify-priority\",\n" 11243 " \"available-notify-exten\",\n" 11244 " \"available-notify-context\",\n" 11245 " User-A is busy:\n" 11246 " \"busy-notify-priority\",\n" 11247 " \"busy-notify-exten\",\n" 11248 " \"busy-notify-context\"\n",
11249 .read = misdn_cc_read,
11265 ast_verb(0,
"-- Unregistering mISDN Channel Driver --\n");
11279 #if defined(AST_MISDN_ENHANCEMENTS) 11296 #if defined(AST_MISDN_ENHANCEMENTS) 11297 misdn_cc_destroy();
11318 int ntflags = 0, ntkc = 0;
11319 char ports[256] =
"";
11336 if (max_ports <= 0) {
11347 #if defined(AST_MISDN_ENHANCEMENTS) 11351 misdn_debug =
ast_malloc(
sizeof(
int) * (max_ports + 1));
11352 if (!misdn_debug) {
11364 misdn_debug[i] = misdn_debug[0];
11368 misdn_debug_only =
ast_calloc(max_ports + 1,
sizeof(
int));
11369 if (!misdn_debug_only) {
11381 misdn_in_calls =
ast_malloc(
sizeof(
int) * (max_ports + 1));
11382 if (!misdn_in_calls) {
11389 misdn_out_calls =
ast_malloc(
sizeof(
int) * (max_ports + 1));
11390 if (!misdn_out_calls) {
11400 misdn_in_calls[i] = 0;
11401 misdn_out_calls[i] = 0;
11433 "misdn_set_opt(:<opt><optarg>:<opt><optarg>...):\n" 11434 "Sets mISDN opts. and optargs\n" 11436 "The available options are:\n" 11437 " a - Have Asterisk detect DTMF tones on called channel\n" 11438 " c - Make crypted outgoing call, optarg is keyindex\n" 11439 " d - Send display text to called phone, text is the optarg\n" 11440 " e - Perform echo cancellation on this channel,\n" 11441 " takes taps as optarg (32,64,128,256)\n" 11442 " e! - Disable echo cancellation on this channel\n" 11443 " f - Enable fax detection\n" 11444 " h - Make digital outgoing call\n" 11445 " h1 - Make HDLC mode digital outgoing call\n" 11446 " i - Ignore detected DTMF tones, don't signal them to Asterisk,\n" 11447 " they will be transported inband.\n" 11448 " jb - Set jitter buffer length, optarg is length\n" 11449 " jt - Set jitter buffer upper threshold, optarg is threshold\n" 11450 " jn - Disable jitter buffer\n" 11451 " n - Disable mISDN DSP on channel.\n" 11452 " Disables: echo cancel, DTMF detection, and volume control.\n" 11453 " p - Caller ID presentation,\n" 11454 " optarg is either 'allowed' or 'restricted'\n" 11455 " s - Send Non-inband DTMF as inband\n" 11456 " vr - Rx gain control, optarg is gain\n" 11457 " vt - Tx gain control, optarg is gain\n" 11462 "misdn_facility(<FACILITY_TYPE>|<ARG1>|..)\n" 11463 "Sends the Facility Message FACILITY_TYPE with \n" 11464 "the given Arguments to the current ISDN Channel\n" 11465 "Supported Facilities are:\n" 11467 "type=calldeflect args=Nr where to deflect\n" 11468 #
if defined(AST_MISDN_ENHANCEMENTS)
11469 "type=callrerouting args=Nr where to deflect\n" 11475 "misdn_check_l2l1(<port>||g:<groupname>,timeout)\n" 11476 "Checks if the L2 and L1 are up on either the given <port> or\n" 11477 "on the ports in the group with <groupname>\n" 11478 "If the L1/L2 are down, check_l2l1 gets up the L1/L2 and waits\n" 11479 "for <timeout> seconds that this happens. Otherwise, nothing happens\n" 11481 "This application, ensures the L1/L2 state of the Ports in a group\n" 11482 "it is intended to make the pmp_l1_check option redundant and to\n" 11483 "fix a buggy switch config from your provider\n" 11485 "a sample dialplan would look like:\n\n" 11486 "exten => _X.,1,misdn_check_l2l1(g:out|2)\n" 11487 "exten => _X.,n,dial(mISDN/g:out/${EXTEN})\n" 11490 #if defined(AST_MISDN_ENHANCEMENTS) 11492 "misdn_command(<command>[,<options>])\n" 11493 "The following commands are defined:\n" 11495 " Setup mISDN support for call completion\n" 11496 " Must call before doing any Dial() involving call completion.\n" 11497 "ccnr-request,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n" 11498 " Request Call Completion No Reply activation\n" 11499 "ccbs-request,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n" 11500 " Request Call Completion Busy Subscriber activation\n" 11501 "cc-b-free,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>\n" 11502 " Set the dialplan location to notify when User-B is available but User-A is busy.\n" 11503 " Setting this dialplan location is optional.\n" 11504 "cc-a-busy,${MISDN_CC_RECORD_ID},<yes/no>\n" 11505 " Set the busy status of call completion User-A\n" 11506 "cc-deactivate,${MISDN_CC_RECORD_ID}\n" 11507 " Deactivate the identified call completion request\n" 11509 "MISDN_CC_RECORD_ID is set when Dial() returns and call completion is possible\n" 11510 "MISDN_CC_STATUS is set to ACTIVATED or ERROR after the call completion\n" 11511 "activation request.\n" 11512 "MISDN_ERROR_MSG is set to a descriptive message on error.\n" 11526 chan_misdn_log(4, 0,
"Adding L1watcher task: port:%d timeout:%ds\n", port, l1timeout);
11531 chan_misdn_log(0, 0,
"-- mISDN Channel Driver Registered --\n");
11547 #if defined(AST_MISDN_ENHANCEMENTS) 11557 #if defined(AST_MISDN_ENHANCEMENTS) 11558 static void misdn_cc_caller_destroy(
void *obj)
11564 #if defined(AST_MISDN_ENHANCEMENTS) 11565 static struct misdn_cc_caller *misdn_cc_caller_alloc(
struct ast_channel *chan)
11567 struct misdn_cc_caller *cc_caller;
11569 if (!(cc_caller =
ao2_alloc(
sizeof(*cc_caller), misdn_cc_caller_destroy))) {
11573 cc_caller->chan = chan;
11579 #if defined(AST_MISDN_ENHANCEMENTS) 11590 static int misdn_command_cc_initialize(
struct ast_channel *chan,
struct misdn_command_args *subcommand)
11592 struct misdn_cc_caller *cc_caller;
11595 if (!(cc_caller = misdn_cc_caller_alloc(chan))) {
11607 datastore->
data = cc_caller;
11620 #if defined(AST_MISDN_ENHANCEMENTS) 11635 static int misdn_command_cc_deactivate(
struct ast_channel *chan,
struct misdn_command_args *subcommand)
11638 const char *error_str;
11639 struct misdn_cc_record *cc_record;
11643 static const char cmd_help[] =
"%s(%s,${MISDN_CC_RECORD_ID})\n";
11645 if (
ast_strlen_zero(subcommand->arg[0]) || !isdigit(*subcommand->arg[0])) {
11649 record_id = atol(subcommand->arg[0]);
11652 cc_record = misdn_cc_find_by_id(record_id);
11653 if (cc_record && 0 <= cc_record->port) {
11654 if (cc_record->ptp) {
11655 if (cc_record->mode.ptp.bc) {
11657 bc = cc_record->mode.ptp.bc;
11658 bc->
fac_out.Function = Fac_None;
11662 misdn_cc_delete(cc_record);
11663 }
else if (cc_record->activated) {
11664 cc_record->error_code = FacError_None;
11665 cc_record->reject_code = FacReject_None;
11666 cc_record->invoke_id = ++misdn_invoke_id;
11667 cc_record->outstanding_message = 1;
11671 dummy.
fac_out.Function = Fac_CCBSDeactivate;
11672 dummy.
fac_out.u.CCBSDeactivate.InvokeID = cc_record->invoke_id;
11673 dummy.
fac_out.u.CCBSDeactivate.ComponentType = FacComponent_Invoke;
11674 dummy.
fac_out.u.CCBSDeactivate.Component.Invoke.CCBSReference = cc_record->mode.ptmp.reference_id;
11684 misdn_cc_response_wait(chan, MISDN_CC_REQUEST_WAIT_MAX, record_id);
11687 cc_record = misdn_cc_find_by_id(record_id);
11689 if (cc_record->port < 0) {
11692 }
else if (cc_record->outstanding_message) {
11693 cc_record->outstanding_message = 0;
11694 error_str = misdn_no_response_from_network;
11695 }
else if (cc_record->reject_code != FacReject_None) {
11696 error_str = misdn_to_str_reject_code(cc_record->reject_code);
11697 }
else if (cc_record->error_code != FacError_None) {
11698 error_str = misdn_to_str_error_code(cc_record->error_code);
11703 misdn_cc_delete(cc_record);
11709 ast_verb(1,
"%s(%s) diagnostic '%s' on channel %s\n",
11718 #if defined(AST_MISDN_ENHANCEMENTS) 11733 static int misdn_command_cc_a_busy(
struct ast_channel *chan,
struct misdn_command_args *subcommand)
11737 struct misdn_cc_record *cc_record;
11740 static const char cmd_help[] =
"%s(%s,${MISDN_CC_RECORD_ID},<yes/no>)\n";
11742 if (
ast_strlen_zero(subcommand->arg[0]) || !isdigit(*subcommand->arg[0])) {
11746 record_id = atol(subcommand->arg[0]);
11748 if (
ast_true(subcommand->arg[1])) {
11750 }
else if (
ast_false(subcommand->arg[1])) {
11758 cc_record = misdn_cc_find_by_id(record_id);
11759 if (cc_record && cc_record->party_a_free != party_a_free) {
11761 cc_record->party_a_free = party_a_free;
11763 if (cc_record->ptp && cc_record->mode.ptp.bc) {
11764 cc_record->error_code = FacError_None;
11765 cc_record->reject_code = FacReject_None;
11768 bc = cc_record->mode.ptp.bc;
11769 if (cc_record->party_a_free) {
11770 bc->
fac_out.Function = Fac_CCBS_T_Resume;
11771 bc->
fac_out.u.CCBS_T_Resume.InvokeID = ++misdn_invoke_id;
11773 bc->
fac_out.Function = Fac_CCBS_T_Suspend;
11774 bc->
fac_out.u.CCBS_T_Suspend.InvokeID = ++misdn_invoke_id;
11788 #if defined(AST_MISDN_ENHANCEMENTS) 11803 static int misdn_command_cc_b_free(
struct ast_channel *chan,
struct misdn_command_args *subcommand)
11810 struct misdn_cc_record *cc_record;
11812 static const char cmd_help[] =
"%s(%s,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>)\n";
11815 for (index = 0; index < 4; ++index) {
11823 if (!isdigit(*subcommand->arg[0]) || !isdigit(*subcommand->arg[3])) {
11828 record_id = atol(subcommand->arg[0]);
11829 context = subcommand->arg[1];
11830 exten = subcommand->arg[2];
11831 priority = atoi(subcommand->arg[3]);
11834 cc_record = misdn_cc_find_by_id(record_id);
11837 ast_copy_string(cc_record->b_free.context, context,
sizeof(cc_record->b_free.context));
11838 ast_copy_string(cc_record->b_free.exten, exten,
sizeof(cc_record->b_free.exten));
11839 cc_record->b_free.priority =
priority;
11847 #if defined(AST_MISDN_ENHANCEMENTS) 11848 struct misdn_cc_request {
11849 enum FacFunction ptmp;
11850 enum FacFunction
ptp;
11854 #if defined(AST_MISDN_ENHANCEMENTS) 11871 static int misdn_command_cc_request(
struct ast_channel *chan,
struct misdn_command_args *subcommand,
const struct misdn_cc_request *
request)
11874 int request_retention;
11879 const char *error_str;
11880 struct misdn_cc_record *cc_record;
11885 static const char cmd_help[] =
"%s(%s,${MISDN_CC_RECORD_ID},<notify-context>,<user-a-extension>,<priority>)\n";
11888 for (index = 0; index < 4; ++index) {
11896 if (!isdigit(*subcommand->arg[0]) || !isdigit(*subcommand->arg[3])) {
11901 record_id = atol(subcommand->arg[0]);
11902 context = subcommand->arg[1];
11903 exten = subcommand->arg[2];
11904 priority = atoi(subcommand->arg[3]);
11907 cc_record = misdn_cc_find_by_id(record_id);
11911 sizeof(cc_record->remote_user_free.context));
11913 sizeof(cc_record->remote_user_free.exten));
11914 cc_record->remote_user_free.priority =
priority;
11916 if (0 <= cc_record->port) {
11917 if (cc_record->ptp) {
11918 if (!cc_record->mode.ptp.bc) {
11919 bc = misdn_lib_get_register_bc(cc_record->port);
11921 cc_record->mode.ptp.bc =
bc;
11922 cc_record->error_code = FacError_None;
11923 cc_record->reject_code = FacReject_None;
11924 cc_record->invoke_id = ++misdn_invoke_id;
11925 cc_record->outstanding_message = 1;
11926 cc_record->activation_requested = 1;
11929 &request_retention,
sizeof(request_retention));
11930 cc_record->mode.ptp.requested_retention = request_retention ? 1 : 0;
11933 bc->
fac_out.Function = request->ptp;
11934 bc->
fac_out.u.CCBS_T_Request.InvokeID = cc_record->invoke_id;
11935 bc->
fac_out.u.CCBS_T_Request.ComponentType = FacComponent_Invoke;
11936 bc->
fac_out.u.CCBS_T_Request.Component.Invoke.Q931ie =
11937 cc_record->redial.setup_bc_hlc_llc;
11938 memset(&
id, 0,
sizeof(
id));
11939 id.number_plan = cc_record->redial.dialed.number_plan;
11940 id.number_type = cc_record->redial.dialed.number_type;
11942 sizeof(
id.number));
11943 misdn_Address_fill(
11944 &bc->
fac_out.u.CCBS_T_Request.Component.Invoke.Destination,
11946 misdn_Address_fill(
11947 &bc->
fac_out.u.CCBS_T_Request.Component.Invoke.Originating,
11948 &cc_record->redial.caller);
11949 bc->
fac_out.u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicatorPresent = 1;
11950 bc->
fac_out.u.CCBS_T_Request.Component.Invoke.PresentationAllowedIndicator =
11951 (cc_record->redial.caller.presentation != 0) ? 0 : 1;
11952 bc->
fac_out.u.CCBS_T_Request.Component.Invoke.RetentionSupported =
11953 request_retention ? 1 : 0;
11961 cc_record->error_code = FacError_None;
11962 cc_record->reject_code = FacReject_None;
11963 cc_record->invoke_id = ++misdn_invoke_id;
11964 cc_record->outstanding_message = 1;
11965 cc_record->activation_requested = 1;
11970 dummy.
fac_out.Function = request->ptmp;
11971 dummy.
fac_out.u.CCBSRequest.InvokeID = cc_record->invoke_id;
11972 dummy.
fac_out.u.CCBSRequest.ComponentType = FacComponent_Invoke;
11973 dummy.
fac_out.u.CCBSRequest.Component.Invoke.CallLinkageID =
11974 cc_record->mode.ptmp.linkage_id;
11985 misdn_cc_response_wait(chan, MISDN_CC_REQUEST_WAIT_MAX, record_id);
11988 cc_record = misdn_cc_find_by_id(record_id);
11990 if (!cc_record->activated) {
11991 if (cc_record->port < 0) {
11993 error_str =
"No port number";
11994 }
else if (cc_record->outstanding_message) {
11995 cc_record->outstanding_message = 0;
11996 error_str = misdn_no_response_from_network;
11997 }
else if (cc_record->reject_code != FacReject_None) {
11998 error_str = misdn_to_str_reject_code(cc_record->reject_code);
11999 }
else if (cc_record->error_code != FacError_None) {
12000 error_str = misdn_to_str_error_code(cc_record->error_code);
12001 }
else if (cc_record->ptp) {
12002 if (cc_record->mode.ptp.bc) {
12003 error_str =
"Call-completion already requested";
12005 error_str =
"Could not allocate call-completion signaling link";
12009 error_str =
"Unexpected error";
12013 if (cc_record->ptp && cc_record->mode.ptp.bc) {
12015 bc = cc_record->mode.ptp.bc;
12016 bc->
fac_out.Function = Fac_None;
12020 misdn_cc_delete(cc_record);
12025 error_str = misdn_cc_record_not_found;
12029 ast_verb(1,
"%s(%s) diagnostic '%s' on channel %s\n",
12041 #if defined(AST_MISDN_ENHANCEMENTS) 12056 static int misdn_command_ccbs_request(
struct ast_channel *chan,
struct misdn_command_args *subcommand)
12058 static const struct misdn_cc_request request = {
12059 .ptmp = Fac_CCBSRequest,
12060 .ptp = Fac_CCBS_T_Request
12063 return misdn_command_cc_request(chan, subcommand, &request);
12067 #if defined(AST_MISDN_ENHANCEMENTS) 12082 static int misdn_command_ccnr_request(
struct ast_channel *chan,
struct misdn_command_args *subcommand)
12084 static const struct misdn_cc_request request = {
12085 .ptmp = Fac_CCNRRequest,
12086 .ptp = Fac_CCNR_T_Request
12089 return misdn_command_cc_request(chan, subcommand, &request);
12093 #if defined(AST_MISDN_ENHANCEMENTS) 12094 struct misdn_command_table {
12099 int (*func)(
struct ast_channel *chan,
struct misdn_command_args *subcommand);
12104 static const struct misdn_command_table misdn_commands[] = {
12107 {
"cc-initialize", misdn_command_cc_initialize, 0 },
12108 {
"cc-deactivate", misdn_command_cc_deactivate, 0 },
12109 {
"cc-a-busy", misdn_command_cc_a_busy, 0 },
12110 {
"cc-b-free", misdn_command_cc_b_free, 0 },
12111 {
"ccbs-request", misdn_command_ccbs_request, 0 },
12112 {
"ccnr-request", misdn_command_ccnr_request, 0 },
12117 #if defined(AST_MISDN_ENHANCEMENTS) 12128 static int misdn_command_exec(
struct ast_channel *chan,
const char *data)
12132 struct misdn_command_args subcommand;
12139 ast_debug(1,
"%s(%s)\n", misdn_command_name, (
char *) data);
12148 for (index = 0; index <
ARRAY_LEN(misdn_commands); ++index) {
12149 if (strcasecmp(misdn_commands[index].
name, subcommand.name) == 0) {
12150 strcpy(subcommand.name, misdn_commands[index].name);
12151 if (misdn_commands[index].misdn_only
12154 "%s(%s) only makes sense with %s channels!\n",
12155 misdn_command_name, subcommand.name, misdn_type);
12158 return misdn_commands[index].func(chan, &subcommand);
12182 ast_log(
LOG_WARNING,
"misdn_facility only makes sense with %s channels!\n", misdn_type);
12187 ast_log(
LOG_WARNING,
"misdn_facility requires arguments: facility_type[,<args>]\n");
12195 ast_log(
LOG_WARNING,
"misdn_facility requires arguments: facility_type[,<args>]\n");
12199 if (!strcasecmp(
args.facility_type,
"calldeflect")) {
12204 #if defined(AST_MISDN_ENHANCEMENTS) 12205 max_len =
sizeof(ch->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number) - 1;
12206 if (max_len < strlen(
args.arg[0])) {
12208 "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n",
12212 ch->
bc->
fac_out.Function = Fac_CallDeflection;
12213 ch->
bc->
fac_out.u.CallDeflection.InvokeID = ++misdn_invoke_id;
12214 ch->
bc->
fac_out.u.CallDeflection.ComponentType = FacComponent_Invoke;
12215 ch->
bc->
fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUserPresent = 1;
12216 ch->
bc->
fac_out.u.CallDeflection.Component.Invoke.PresentationAllowedToDivertedToUser = 0;
12217 ch->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Type = 0;
12218 ch->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.LengthOfNumber = strlen(
args.arg[0]);
12219 strcpy((
char *) ch->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Party.Number,
args.arg[0]);
12220 ch->
bc->
fac_out.u.CallDeflection.Component.Invoke.Deflection.Subaddress.Length = 0;
12224 max_len =
sizeof(ch->
bc->
fac_out.u.CDeflection.DeflectedToNumber) - 1;
12225 if (max_len < strlen(
args.arg[0])) {
12227 "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n",
12232 ch->
bc->
fac_out.u.CDeflection.PresentationAllowed = 0;
12234 strcpy((
char *) ch->
bc->
fac_out.u.CDeflection.DeflectedToNumber,
args.arg[0]);
12240 #if defined(AST_MISDN_ENHANCEMENTS) 12241 }
else if (!strcasecmp(
args.facility_type,
"callrerouteing")
12242 || !strcasecmp(
args.facility_type,
"callrerouting")) {
12247 max_len =
sizeof(ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number) - 1;
12248 if (max_len < strlen(
args.arg[0])) {
12250 "Facility: Number argument too long (up to %u digits are allowed). Ignoring.\n",
12254 ch->
bc->
fac_out.Function = Fac_CallRerouteing;
12255 ch->
bc->
fac_out.u.CallRerouteing.InvokeID = ++misdn_invoke_id;
12256 ch->
bc->
fac_out.u.CallRerouteing.ComponentType = FacComponent_Invoke;
12258 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.ReroutingReason = 0;
12259 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.ReroutingCounter = 1;
12261 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Type = 0;
12262 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.LengthOfNumber = strlen(
args.arg[0]);
12263 strcpy((
char *) ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Party.Number,
args.arg[0]);
12264 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CalledAddress.Subaddress.Length = 0;
12266 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.CallingPartySubaddress.Length = 0;
12269 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Length = 3;
12270 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[0] = 0x90;
12271 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[1] = 0x90;
12272 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Bc.Contents[2] = 0xa3;
12273 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Hlc.Length = 0;
12274 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.Llc.Length = 0;
12275 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.Q931ie.UserInfo.Length = 0;
12277 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.LastRerouting.Type = 1;
12278 ch->
bc->
fac_out.u.CallRerouteing.Component.Invoke.SubscriptionOption = 0;
12314 if (
args.argc != 2) {
12320 timeout = atoi(
args.timeout);
12321 port_str =
args.grouppar;
12323 if (port_str[0] ==
'g' && port_str[1] ==
':') {
12338 if (!strcasecmp(cfg_group, group)) {
12348 port = atoi(port_str);
12374 int change_jitter = 0;
12377 ast_log(
LOG_WARNING,
"misdn_set_opt makes sense only with %s channels!\n", misdn_type);
12387 for (tok = strtok_r(parse,
":", &tokb);
12389 tok = strtok_r(
NULL,
":", &tokb)) {
12392 if (tok[0] ==
'!') {
12413 ch->
jb_len = atoi(++tok);
12437 rxgain = atoi(++tok);
12448 txgain = atoi(++tok);
12461 keyidx = atoi(++tok);
12470 for (i = 0; i < keyidx; i++) {
12471 key =
strsep(&tmp,
",");
12487 *ch->
bc->pipeline = 0;
12493 update_pipeline_config(ch->
bc);
12507 if (strlen(tok) > 1 && tok[1] ==
'1') {
12531 if (strstr(tok,
"allowed")) {
12534 }
else if (strstr(tok,
"restricted")) {
12537 }
else if (strstr(tok,
"not_screened")) {
12552 if (change_jitter) {
12657 if (!jb || ! data) {
12666 for (i = 0; i <
len; i++) {
12669 wp = (wp != jb->
size - 1) ? wp + 1 : 0;
12671 if (wp == jb->
rp) {
12688 rp = (rp != 0) ? rp - 1 : jb->
size - 1;
12729 for (i = 0; i <
len; i++) {
12738 if (jb->
ok[rp] == 1) {
12741 rp = (rp != jb->
size - 1) ? rp + 1 : 0;
12756 chan_misdn_log(9, 0,
"misdn_jb_empty: Wait...requested:%d p:%p\n", len, jb);
12774 if (!(0 <= port && port <= max_ports)) {
12775 ast_log(
LOG_WARNING,
"chan_misdn_log called with out-of-range port number! (%d)\n", port);
12778 }
else if (!(level == -1
12779 || (misdn_debug_only[port]
12780 ? (level == 1 && misdn_debug[port]) || level == misdn_debug[port]
12781 : level <= misdn_debug[port])
12790 snprintf(port_buf,
sizeof(port_buf),
"P[%2d] ", port);
12791 va_start(ap, tmpl);
12792 vsnprintf(buf,
sizeof(buf), tmpl, ap);
12797 }
else if (misdn_debug_only[port]
12798 ? (level == 1 && misdn_debug[port]) || level == misdn_debug[port]
12799 : level <= misdn_debug[port]) {
12817 tmp = ctime_r(&tm, ctimebuf);
12818 p = strchr(tmp,
'\n');
12824 fputs(port_buf, fp);
static int misdn_send_text(struct ast_channel *chan, const char *text)
int ast_dsp
TRUE if we will use the Asterisk DSP to detect DTMF/Fax.
int misdn_lib_maxports_get(void)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
int need_busy
TRUE if we could send an AST_CONTROL_BUSY if needed.
static void chan_misdn_log(int level, int port, char *tmpl,...)
#define AST_CAUSE_PROTOCOL_ERROR
int ast_dtmf_stream(struct ast_channel *chan, struct ast_channel *peer, const char *digits, int between, unsigned int duration)
Send a string of DTMF digits to a channel.
int misdn_lib_init(char *portlist, struct misdn_lib_iface *iface, void *user_data)
int ast_safe_sleep(struct ast_channel *chan, int ms)
Wait for a specified amount of time, looking for hangups.
struct ast_channel * ast_waitfor_n(struct ast_channel **chan, int n, int *ms)
Waits for input on a group of channels Wait for input on an array of channels for a given # of millis...
unsigned long long ast_group_t
char keypad[MISDN_MAX_KEYPAD_LEN]
Q.931 Keypad Facility IE contents.
Information needed to identify an endpoint in a call.
enum sip_cc_notify_state state
static int ast_to_misdn_pres(int presentation)
static int misdn_digit_begin(struct ast_channel *chan, char digit)
void ast_party_connected_line_init(struct ast_party_connected_line *init)
Initialize the given connected line structure.
void ast_channel_pickupgroup_set(struct ast_channel *chan, ast_group_t value)
int display_setup
Put a display ie in the SETUP message.
AST_CONNECTED_LINE_UPDATE_SOURCE
Connected line update source code.
void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
Set caller ID number, name and ANI and generate AMI event.
#define ast_channel_lock(chan)
static char mohinterpret[MAX_MUSICCLASS]
struct ast_frame * ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf)
Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress...
static char exten[AST_MAX_EXTENSION]
Main Channel structure associated with a channel.
static int stop_indicate(struct chan_list *cl)
struct ast_party_dialed::@246 number
Dialed/Called number.
int jb_len
Jitterbuffer length.
#define AST_CLI_DEFINE(fn, txt,...)
static struct chan_list * find_hold_call(struct misdn_bchannel *bc)
char * str
Subscriber phone number (Malloced)
const char * ast_named_caller_presentation(int data)
Convert caller ID pres value to text code.
int faxdetect
Fax detection option. (0:no 1:yes 2:yes+nojump)
void debug_numtype(int port, int numtype, char *type)
struct FacParm fac_out
Outbound FACILITY message function type and contents.
#define AST_LIST_LOCK(head)
Locks a list.
int misdn_cfg_get_next_port_spin(int port)
static void hanguptone_indicate(struct chan_list *cl)
static void wait_for_digits(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan)
#define AST_CAUSE_INCOMPATIBLE_DESTINATION
static const char * misdn_to_str_ton(enum mISDN_NUMBER_TYPE number_type)
struct chan_list * next
Next channel call record in the list.
Asterisk main include file. File version handling, generic pbx functions.
char number[MISDN_MAX_NUMBER_LEN]
Phone number (Address)
void misdn_lib_nt_debug_init(int flags, char *file)
enum ast_transfer_result ast_bridge_transfer_attended(struct ast_channel *to_transferee, struct ast_channel *to_transfer_target)
Attended transfer.
static char * handle_cli_misdn_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
struct ast_party_id priv_to
Call is redirecting to a new party (Sent to the caller) - private representation. ...
char ast_rd_buf[4096]
Read buffer for inbound audio from pipe[0].
struct ast_features_pickup_config * ast_get_chan_features_pickup_config(struct ast_channel *chan)
Get the pickup configuration options for a channel.
char * str
Subscriber phone number (Malloced)
void ast_channel_set_caller_event(struct ast_channel *chan, const struct ast_party_caller *caller, const struct ast_set_party_caller *update)
Set the caller id information in the Asterisk channel and generate an AMI event if the caller id name...
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
static void update_config(struct chan_list *ch)
Updates caller ID information from config.
void * ast_channel_generatordata(const struct ast_channel *chan)
struct ast_set_party_id ani
int misdn_lib_pid_restart(int pid)
struct ast_party_id ast_channel_redirecting_effective_from(struct ast_channel *chan)
unsigned short ast_channel_transfercapability(const struct ast_channel *chan)
static char * handle_cli_misdn_port_down(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
struct ast_dsp * dsp
Allocated DSP controller.
static int read_config(struct chan_list *ch)
union misdn_bchannel::@161 AOCD
static int misdn_to_ast_plan(enum mISDN_NUMBER_PLAN number_plan)
String manipulation functions.
int presentation
Q.931 presentation-indicator and screening-indicator encoded fields.
int need_hangup
TRUE if a channel can be hung up by calling asterisk directly when done.
int nodsp
TRUE if we will not use jollys dsp.
void misdn_cfg_destroy(void)
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
int need_queue_hangup
TRUE if a hangup needs to be queued.
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
struct ast_party_id id
Connected party ID.
void ast_party_id_reset(struct ast_party_id *id)
Destroy and initialize the given party id structure.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_CAUSE_NORMAL_TEMPORARY_FAILURE
#define ast_channel_unref(c)
Decrease channel reference count.
int misdn_cfg_get_next_port(int port)
int addr
From associated B channel: B Channel mISDN driver layer ID from mISDN_get_layerid() ...
static void misdn_update_redirecting(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
int txgain
Tx gain setting (range -8 to 8)
#define AST_CAUSE_SWITCH_CONGESTION
static struct ast_channel * misdn_new(struct chan_list *cl, int state, char *exten, char *callerid, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, int port, int c)
struct ast_party_id priv_orig
Who originally redirected the call (Sent to the party the call is redirected toward) - private repres...
int ec_enable
TRUE if the echo cancellor is enabled.
enum FacFunction AOCDtype
Support for translation of data formats. translate.c.
int tone_cnt
Number of tone samples to generate.
Time-related functions and macros.
int ignore_dtmf
TRUE if DTMF digits are to be passed inband only.
int presentation
User set presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
struct ast_party_name name
Subscriber name.
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
struct ast_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
int uulen
User-User information string length in uu[].
void ast_dsp_free(struct ast_dsp *dsp)
#define DSP_FEATURE_DIGIT_DETECT
char uu[256]
User-User information string.
#define AST_CAUSE_UNALLOCATED
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
static int misdn_attempt_transfer(struct chan_list *active_ch, struct chan_list *held_ch)
int dummy
TRUE if this is a dummy BC record.
int pipe[2]
Pipe file descriptor handles array. Read from pipe[0], write to pipe[1].
static char * handle_cli_misdn_toggle_echocancel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
void misdn_dump_chanlist(void)
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Convenient Signal Processing routines.
static void hold(struct ast_channel *chan)
Helper method to place a channel in a bridge on hold.
static void misdn_update_caller_id(struct ast_channel *ast, const struct misdn_party_id *id, char *cid_tag)
struct ast_channel * ast_channel_release(struct ast_channel *chan)
Unlink and release reference to a channel.
#define AST_CAUSE_NETWORK_OUT_OF_ORDER
static int misdn_to_ast_pres(int presentation)
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
static void cl_queue_chan(struct chan_list *chan)
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
static void release_chan_early(struct chan_list *ch)
#define DEADLOCK_AVOIDANCE(lock)
static int pbx_start_chan(struct chan_list *ch)
int bframe_len
B channel speech sample data buffer size.
descriptor for a cli entry.
void manager_ec_enable(struct misdn_bchannel *bc)
static int cl_dequeue_chan(struct chan_list *chan)
struct misdn_jb * jb
Allocated jitterbuffer controller.
enum ast_pbx_result ast_pbx_start(struct ast_channel *c)
Create a new thread and start the PBX.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
char * manager_isdn_get_info(enum event_e event)
char incoming_cid_tag[MISDN_MAX_NAME_LEN]
Incoming Caller ID string tag for special purpose.
static void misdn_update_connected_line(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
struct ast_jb_conf * misdn_get_global_jbconf(void)
static int misdn_hangup(struct ast_channel *ast)
static void dummy(char *unused,...)
void misdn_jb_destroy(struct misdn_jb *jb)
frees the data and destroys the given jitterbuffer struct
int faxdetect_timeout
Number of seconds to detect a Fax machine when detection enabled.
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
static const struct allowed_bearers allowed_bearers_array[]
void misdn_cfg_get_config_string(int port, enum misdn_cfg_elements elem, char *buf, int bufsize)
int misdn_jb_fill(struct misdn_jb *jb, const char *data, int len)
fills the jitterbuffer with len data returns < 0 if there was an error (buffer overrun).
int cw
TRUE if call waiting.
Connected-Line/Calling/Redirecting ID info struct.
void misdn_make_dummy(struct misdn_bchannel *dummybc, int port, int l3id, int nt, int channel)
struct ast_party_id priv_from
Who is redirecting the call (Sent to the party the call is redirected toward) - private representatio...
int hdlc
TRUE if call made in digital HDLC mode.
void misdn_lib_tone_generator_start(struct misdn_bchannel *bc)
mISDN_REDIRECTING_REASON
Q.931 encoded redirecting reason.
static void release_chan(struct chan_list *ch, struct misdn_bchannel *bc)
struct ast_tone_zone * ast_channel_zone(const struct ast_channel *chan)
int add_out_calls(int port)
int misdn_cfg_init(int max_ports, int reload)
struct ast_frame frame
Inbound audio frame returned by misdn_read().
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
int misdn_cfg_is_port_valid(int port)
static int misdn_tasks_add(int timeout, ast_sched_cb callback, const void *data)
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
struct hold_info hold
HELD channel call information.
int jb_upper_threshold
Jitterbuffer upper threshold.
B channel control structure.
#define AST_PRES_USER_NUMBER_FAILED_SCREEN
int outgoing_colp
Select what to do with outgoing COLP information.
int presentation
Number presentation restriction code 0=Allowed, 1=Restricted, 2=Unavailable.
int ast_sched_add_variable(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) attribute_warn_unused_result
Adds a scheduled event with rescheduling support.
Structure to pass both assignedid values to channel drivers.
static struct robin_list * robin
int sending_complete
TRUE if all digits necessary to complete the call are available. No more INFORMATION messages are nee...
Structure for a data store type.
void ast_channel_callgroup_set(struct ast_channel *chan, ast_group_t value)
static void config_jitterbuffer(struct chan_list *ch)
static const char * misdn_get_ch_state(struct chan_list *p)
void misdn_cfg_reload(void)
ast_channel_state
ast_channel states
char * str
Subscriber name (Malloced)
static char * handle_cli_misdn_set_tics(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static struct chan_list * find_hold_active_call(struct misdn_bchannel *bc)
static struct chan_list * get_chan_by_ast_name(const char *name)
char crypt_key[255]
Blowfish encryption key string (secret)
static void misdn_copy_redirecting_to_ast(struct ast_channel *ast, const struct misdn_party_redirecting *redirect, char *tag)
struct ast_party_id ast_channel_redirecting_effective_to(struct ast_channel *chan)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
void ast_channel_named_pickupgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
#define MISDN_ASTERISK_TECH_PVT(ast)
#define AST_DEFINE_APP_ARGS_TYPE(type, arglist)
Define a structure type to hold an application's arguments.
static struct ast_threadstorage buf2
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
static char * handle_cli_misdn_restart_port(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int(* generate)(struct ast_channel *chan, void *data, int len, int samples)
static void start_pbx(struct chan_list *ch, struct misdn_bchannel *bc, struct ast_channel *chan)
int capability
SETUP message bearer capability field code value.
#define ast_mutex_lock(a)
void misdn_lib_tone_generator_stop(struct misdn_bchannel *bc)
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
void ast_verbose(const char *fmt,...)
static int * misdn_debug_only
#define ast_strdup(str)
A wrapper for strdup()
Structure for a data store object.
void misdn_lib_destroy(void)
static const char * misdn_to_str_pres(int presentation)
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
struct misdn_bchannel * misdn_lib_find_held_bc(int port, int l3_id)
Find a held call's B channel record.
void ast_playtones_stop(struct ast_channel *chan)
Stop playing tones on a channel.
int AOCD_need_export
TRUE if AOCDtype and AOCD data are ready to export to Asterisk.
char context[AST_MAX_CONTEXT]
Incoming call dialplan context identifier.
I/O Management (derived from Cheops-NG)
char mohinterpret[MAX_MUSICCLASS]
The configured music-on-hold class to use for this call.
static struct chan_list * cl_te
Global channel call record list head.
#define AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
Common implementation-independent jitterbuffer stuff.
void ast_cli(int fd, const char *fmt,...)
static char * handle_cli_misdn_restart_pid(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int misdn_chan_is_valid(struct chan_list *ch)
void import_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
Import parameters from the dialplan environment variables.
#define AST_CAUSE_INVALID_NUMBER_FORMAT
struct ast_channel * ast
Associated Asterisk channel structure.
static const char * misdn_to_str_plan(enum mISDN_NUMBER_PLAN number_plan)
int ast_unregister_application(const char *app)
Unregister an application.
int chan_misdn_jb_empty(struct misdn_bchannel *bc, char *buf, int len)
void ast_moh_stop(struct ast_channel *chan)
Turn off music on hold on a given channel.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_PRES_NETWORK_NUMBER
static char cid_num[AST_MAX_EXTENSION]
int misdn_lib_get_maxchans(int port)
void isdn_lib_update_rxgain(struct misdn_bchannel *bc)
int code
enum AST_REDIRECTING_REASON value for redirection
struct misdn_party_id to
Where the call is being redirected toward (Sent to the calling party)
#define ast_verb(level,...)
static void chan_list_destructor(void *obj)
Indicate what information in ast_party_caller should be set.
int notxtone
TRUE if we are not to generate tones (Playtones)
void misdn_cfg_get_name(enum misdn_cfg_elements elem, void *buf, int bufsize)
static char * handle_cli_misdn_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
static void do_immediate_setup(struct misdn_bchannel *bc, struct chan_list *ch, struct ast_channel *ast)
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct ast_frame_subclass subclass
void isdn_lib_update_txgain(struct misdn_bchannel *bc)
int misdn_cap_is_speech(int cap)
static int misdn_tasks_add_variable(int timeout, ast_sched_cb callback, const void *data)
void isdn_lib_update_ec(struct misdn_bchannel *bc)
static int misdn_is_msn_valid(int port, const struct misdn_party_dialing *dialed)
static pthread_t misdn_tasks_thread
void get_show_stack_details(int port, char *buf)
struct timeval overlap_tv
Overlap timer start time. Timer restarted for every digit received.
enum event_response_e(* cb_event)(enum event_e event, struct misdn_bchannel *bc, void *user_data)
char * ast_print_group(char *buf, int buflen, ast_group_t group)
Print call and pickup groups into buffer.
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
#define AST_PRES_RESTRICTED
#define ast_strlen_zero(foo)
static int stop_bc_tones(struct chan_list *cl)
struct ast_set_party_id from
int misdn_cfg_is_group_method(char *group, enum misdn_cfg_method meth)
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
static void misdn_tasks_destroy(void)
static const struct state_struct state_array[]
static void misdn_tasks_init(void)
static int misdn_fixup(struct ast_channel *oldast, struct ast_channel *ast)
static void print_facility(const struct FacParm *fac, const struct misdn_bchannel *bc)
static int misdn_l1_task(const void *vdata)
struct ast_party_id id
Caller party ID.
static char * handle_cli_misdn_port_unblock(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
void ast_change_name(struct ast_channel *chan, const char *newname)
Change channel name.
Configuration File Parser.
static char * handle_cli_misdn_send_display(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static ast_mutex_t release_lock
int misdn_inband_avail(struct misdn_bchannel *bc)
void misdn_lib_split_bridge(struct misdn_bchannel *bc1, struct misdn_bchannel *bc2)
#define ast_debug(level,...)
Log a DEBUG message.
static struct ast_frame * process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame)
int set_presentation
TRUE if the user set the presentation restriction code.
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
char number[MISDN_MAX_NUMBER_LEN]
Dialed/Called Phone Number (Address)
#define AST_CAUSE_NO_ROUTE_TRANSIT_NET
void manager_ec_disable(struct misdn_bchannel *bc)
static void show_config_description(int fd, enum misdn_cfg_elements elem)
char display[84]
Display message that can be displayed by the user phone.
static int misdn_answer(struct ast_channel *ast)
void ast_channel_queue_connected_line_update(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Queue a connected line update frame on a channel.
struct ast_party_id ani
Automatic Number Identification (ANI)
static char * complete_ch(struct ast_cli_args *a)
int pri
TRUE if ISDN-PRI (ISDN-BRI otherwise)
General Asterisk PBX channel definitions.
#define AST_PRES_USER_NUMBER_UNSCREENED
static int misdn_to_ast_ton(enum mISDN_NUMBER_TYPE number_type)
void ast_channel_rings_set(struct ast_channel *chan, int value)
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
int misdn_lib_port_block(int port)
static struct ast_frame * misdn_read(struct ast_channel *ast)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
static int load_module(void)
Load the module.
void ast_channel_generatordata_set(struct ast_channel *chan, void *value)
int need_release_complete
TRUE if RELEASE_COMPLETE needs to be sent to clear a call.
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
static char * handle_cli_misdn_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
#define ast_poll(a, b, c)
void misdn_cfg_get(int port, enum misdn_cfg_elements elem, void *buf, int bufsize)
static struct ast_cli_entry chan_misdn_clis[]
static void misdn_tasks_remove(int task_id)
Data structure associated with a custom dialplan function.
#define ast_register_application(app, execute, synopsis, description)
Register an application.
void misdn_lib_release(struct misdn_bchannel *bc)
int overlap_dial_task
Overlap dialing timeout Task ID. -1 if not running.
#define AST_MAX_EXTENSION
#define AST_CAUSE_NORMAL_CLEARING
Scheduler Routines (derived from cheops)
static int misdn_call(struct ast_channel *ast, const char *dest, int timeout)
Caller Party information.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
int dropped_frame_cnt
Number of outgoing audio frames dropped since last debug gripe message.
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Asterisk internal frame definitions.
#define ao2_ref(o, delta)
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
static const char * misdn_to_str_screen(int screening)
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
void misdn_cfg_get_ports_string(char *ports)
Generate a comma separated list of all active ports.
int nt
TRUE if NT side of protocol (TE otherwise)
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the number.
#define DSP_FEATURE_FAX_DETECT
static char * handle_cli_misdn_show_port(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
void misdn_lib_log_ies(struct misdn_bchannel *bc)
int holded
TRUE if this channel is on hold.
#define ast_strdupa(s)
duplicate a string in memory from the stack
static struct ast_tone_zone_sound * ast_tone_zone_sound_unref(struct ast_tone_zone_sound *ts)
Release a reference to an ast_tone_zone_sound.
#define AST_BRIDGE_DTMF_CHANNEL_1
Report DTMF on channel 1.
struct ast_set_party_id id
int display_connected
Put a display ie in the CONNECT message.
#define MISDN_MAX_NUMBER_LEN
void ast_channel_set_redirecting(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Set the redirecting id information in the Asterisk channel.
int nojitter
TRUE if we will not use the jitter buffer system.
#define ast_malloc(len)
A wrapper for malloc()
char infos_pending[MISDN_MAX_NUMBER_LEN]
Collected digits to go into info_dad[] while waiting for a SETUP_ACKNOWLEDGE to come in...
struct misdn_party_id caller
Originating/Caller ID information struct.
struct timeval faxdetect_tv
Starting time of fax detection with timeout when nonzero.
static struct chan_list * find_chan_by_bc(struct misdn_bchannel *bc)
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
char name[MISDN_MAX_NAME_LEN]
Subscriber Name.
int rxgain
Rx gain setting (range -8 to 8)
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
struct FacAOCDCurrency currency
char * bc_state2str(enum bchannel_state state)
int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
Queue a hold frame.
enum misdn_chan_state state
State of the channel.
AST_REDIRECTING_REASON
redirecting reason codes.
int far_alerting
TRUE if we must do the ringback tones.
Structure to describe a channel "technology", ie a channel driver See for examples: ...
static char global_tracefile[BUFFERSIZE+1]
const char * ast_channel_exten(const struct ast_channel *chan)
Core PBX routines and definitions.
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel's frame queue.
void misdn_cfg_update_ptp(void)
struct ast_set_party_id priv
int misdn_lib_port_unblock(int port)
void misdn_lib_nt_keepcalls(int kc)
#define AST_CAUSE_DESTINATION_OUT_OF_ORDER
static char * complete_show_config(struct ast_cli_args *a)
#define MISDN_ASTERISK_TECH_PVT_SET(ast, value)
int port
Logical port the channel call record is HELD on because the B channel is no longer associated...
int misdn_lib_is_ptp(int port)
enum misdn_cfg_elements misdn_cfg_get_elem(const char *name)
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
static void print_bc_info(int fd, struct chan_list *help, struct misdn_bchannel *bc)
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
char * term_color(char *outbuf, const char *inbuf, int fgcolor, int bgcolor, int maxout)
Colorize a specified string by adding terminal color codes.
struct misdn_party_id connected
Connected-Party/Connected-Line ID information struct.
void export_ch(struct ast_channel *chan, struct misdn_bchannel *bc, struct chan_list *ch)
Export parameters to the dialplan environment variables.
char allowed_bearers[BUFFERSIZE+1]
The "allowed_bearers" string read in from /etc/asterisk/misdn.conf.
Dialed/Called information struct.
int pid
B channel process ID (1-5000)
int misdn_lib_tx2misdn_frm(struct misdn_bchannel *bc, void *data, int len)
int originator
Who originally created this channel. ORG_AST or ORG_MISDN.
struct misdn_party_id from
Who is redirecting the call (Sent to the party the call is redirected toward)
static int send_cause2ast(struct ast_channel *ast, struct misdn_bchannel *bc, struct chan_list *ch)
int dec
TRUE if allocate higher B channels first.
enum mISDN_NUMBER_TYPE number_type
Type-of-number in ISDN terms for the dialed/called number.
static const char * bearer2str(int cap)
static void free_robin_list(void)
static int misdn_write(struct ast_channel *ast, struct ast_frame *frame)
static void sighandler(int sig)
struct ast_generator * ast_channel_generator(const struct ast_channel *chan)
int ast_pickup_call(struct ast_channel *chan)
Pickup a call.
static int misdn_check_l2l1(struct ast_channel *chan, const char *data)
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
static char * handle_cli_misdn_port_block(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
void ast_party_caller_set_init(struct ast_party_caller *init, const struct ast_party_caller *guide)
Initialize the given caller structure using the given guide for a set update operation.
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
static char * handle_cli_misdn_set_crypt_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan)
static void misdn_add_number_prefix(int port, enum mISDN_NUMBER_TYPE number_type, char *number, size_t size)
int plan
Q.931 Type-Of-Number and Numbering-Plan encoded fields.
void ast_channel_named_callgroups_set(struct ast_channel *chan, struct ast_namedgroups *value)
int misdn_lib_send_restart(int port, int channel)
#define AST_PRES_NUMBER_TYPE
static int ast_to_misdn_screen(int screening)
static struct chan_list * find_hold_call_l3(unsigned long l3_id)
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
static struct ast_sched_context * misdn_tasks
the main schedule context for stuff like l1 watcher, overlap dial, ...
static void misdn_update_remote_party(struct ast_channel *ast, const struct misdn_party_id *id, enum AST_CONNECTED_LINE_UPDATE_SOURCE source, char *cid_tag)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int send_dtmf
TRUE if we should produce DTMF tones ourselves.
struct ast_tone_zone_sound * ast_get_indication_tone(const struct ast_tone_zone *zone, const char *indication)
Locate a tone zone sound.
static int misdn_digit_end(struct ast_channel *ast, char digit, unsigned int duration)
static struct ast_channel * misdn_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
Connected Line/Party information.
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
struct misdn_party_redirecting redirecting
Redirecting information struct (Where a call diversion or transfer was invoked)
int ast_moh_start(struct ast_channel *chan, const char *mclass, const char *interpclass)
Turn on music on hold on a given channel.
int incoming_early_audio
TRUE if you want to send Tone Indications to an incoming ISDN channel on a TE Port.
static int misdn_overlap_dial_task(const void *data)
#define ao2_alloc(data_size, destructor_fn)
int port
Logical Layer 1 port associated with this B channel.
int add_in_calls(int port)
int urate
Q.931 Bearer Capability IE Layer 1 User Rate field.
Redirecting Line information. RDNIS (Redirecting Directory Number Information Service) Where a call d...
struct misdn_party_dialing dialed
Dialed/Called information struct.
static void misdn_tasks_wakeup(void)
struct ast_format_cap * capabilities
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
static char * handle_cli_misdn_show_config(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
void misdn_cfg_get_desc(enum misdn_cfg_elements elem, void *buf, int bufsize, void *buf_default, int bufsize_default)
static const char misdn_type[]
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
static int dialtone_indicate(struct chan_list *cl)
ast_mutex_t overlap_tv_lock
overlap_tv access lock.
static struct ast_channel_tech misdn_tech
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
static int unload_module(void)
static void misdn_copy_redirecting_from_ast(struct misdn_bchannel *bc, struct ast_channel *ast)
static char * handle_cli_misdn_send_facility(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int misdn_lib_get_port_up(int port)
#define ast_channel_unlock(chan)
static void parse(struct mgcp_request *req)
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
int source
Information about the source of an update.
#define ast_calloc(num, len)
A wrapper for calloc()
int addr
B Channel mISDN driver layer ID from mISDN_get_layerid()
void misdn_lib_send_tone(struct misdn_bchannel *bc, enum tone_e tone)
int active
Seems to have been intended for something to do with the jitter buffer.
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
#define AST_CAUSE_NUMBER_CHANGED
static enum AST_REDIRECTING_REASON misdn_to_ast_reason(const enum mISDN_REDIRECTING_REASON q931)
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
struct misdn_bchannel * misdn_lib_get_free_bc(int port, int channel, int inout, int dec)
static int _misdn_tasks_add_variable(int timeout, ast_sched_cb callback, const void *data, int variable)
static void reload_config(void)
static void * misdn_tasks_thread_func(void *data)
Module has failed to load, may be in an inconsistent state.
Channel call record structure.
static char * handle_cli_misdn_send_restart(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define DATASTORE_INHERIT_FOREVER
static enum mISDN_NUMBER_TYPE ast_to_misdn_ton(unsigned ast_number_type)
int misdn_lib_port_up(int port, int check)
int misdn_lib_port_is_nt(int port)
static int request(void *obj)
static int update_ec_config(struct misdn_bchannel *bc)
static int * misdn_out_calls
static void misdn_prefix_string(const char *str_prefix, char *str_main, size_t size)
unsigned int l3id
From associated B channel: Layer 3 process ID.
int to_changed
TRUE if the redirecting.to information has changed.
struct ast_party_redirecting_reason reason
Reason for the redirection.
int(* ast_sched_cb)(const void *data)
scheduler callback
#define chan_list_ref(obj, debug)
enum misdn_hold_state state
Call HOLD state.
static struct chan_list * chan_list_init(int orig)
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
int channel
Original B channel number the HELD call was using.
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
static char cid_name[AST_MAX_EXTENSION]
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
int channel
Assigned B channel number B1, B2... 0 if not assigned.
Indicate what information in ast_party_connected_line should be set.
void ast_jb_configure(struct ast_channel *chan, const struct ast_jb_conf *conf)
Configures a jitterbuffer on a channel.
static void hangup_chan(struct chan_list *ch, struct misdn_bchannel *bc)
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
static int g_config_initialized
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
#define AST_PRES_RESTRICTION
static void print_bearer(struct misdn_bchannel *bc)
#define AST_PRES_USER_NUMBER_PASSED_SCREEN
static void export_aoc_vars(int originator, struct ast_channel *ast, struct misdn_bchannel *bc)
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
int out_cause
Q.931 Cause for disconnection code (sent)
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
char * tag
User-set "tag".
struct ast_set_party_id id
void ast_deactivate_generator(struct ast_channel *chan)
void ast_party_redirecting_free(struct ast_party_redirecting *doomed)
Destroy the redirecting information contents.
char * strsep(char **str, const char *delims)
struct ast_set_party_id to
enum mISDN_REDIRECTING_REASON reason
Reason a call is being redirected (Q.931 field value)
#define AST_CAUSE_NO_ROUTE_DESTINATION
void misdn_lib_isdn_l1watcher(int port)
int need_release
TRUE if RELEASE needs to be sent to clear a call.
struct ast_tone_zone_sound * ts
Tone zone sound used for dialtone generation.
#define ast_channel_ref(c)
Increase channel reference count.
int need_more_infos
TRUE if we send SETUP_ACKNOWLEDGE on incoming calls anyway (instead of PROCEEDING).
int dtmf
Last decoded DTMF digit from mISDN driver.
enum bchannel_state bc_state
Current B Channel state.
Indicate what information in ast_party_redirecting should be set.
int count
Number of times the call was redirected.
Standard Command Line Interface.
int ast_channel_hangupcause(const struct ast_channel *chan)
static int start_bc_tones(struct chan_list *cl)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
struct ast_party_id to
Call is redirecting to a new party (Sent to the caller)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
int faxhandled
TRUE if a fax has been detected.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
int need_disconnect
TRUE if DISCONNECT needs to be sent to clear a call.
int misdn_lib_port_is_pri(int port)
struct ast_channel * ast_channel_bridge_peer(struct ast_channel *chan)
Get the channel's bridge peer only if the bridge is two-party.
const char * ast_channel_name(const struct ast_channel *chan)
void ast_party_redirecting_init(struct ast_party_redirecting *init)
Initialize the given redirecting structure.
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
#define AST_CAUSE_USER_BUSY
int misdn_lib_get_port_down(int port)
void ast_channel_transfercapability_set(struct ast_channel *chan, unsigned short value)
int ast_setstate(struct ast_channel *chan, enum ast_channel_state)
Change the state of a channel.
enum mISDN_NOTIFY_CODE notify_description_code
Notification indicator ie description code.
int ast_async_goto(struct ast_channel *chan, const char *context, const char *exten, int priority)
Set the channel to next execute the specified dialplan location.
char * ast_transfercapability2str(int transfercapability) attribute_const
Gives the string form of a given transfer capability.
static char * complete_debug_port(struct ast_cli_args *a)
int ast_sched_wait(struct ast_sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place.
static void misdn_get_connected_line(struct ast_channel *ast, struct misdn_bchannel *bc, int originator)
void isdn_lib_stop_dtmf(struct misdn_bchannel *bc)
char * ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
Command completion for the list of active channels.
Data structure associated with a single frame of data.
int progress_indicator
Progress Indicator IE progress description field. Used to determine if there is an inband audio messa...
Internal Asterisk hangup causes.
void ast_party_redirecting_set_init(struct ast_party_redirecting *init, const struct ast_party_redirecting *guide)
Initialize the given redirecting id structure using the given guide for a set update operation...
int misdn_lib_send_event(struct misdn_bchannel *bc, enum event_e event)
int ast_playtones_start(struct ast_channel *chan, int vol, const char *tonelist, int interruptible)
Start playing a list of tones on a channel.
int ec_deftaps
Number of taps in the echo cancellor when enabled.
int misdn_lib_port_restart(int port)
const char * ast_channel_context(const struct ast_channel *chan)
Handy terminal functions for vt* terms.
const char * data
Description of a tone.
#define ast_datastore_alloc(info, uid)
union ast_frame::@263 data
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
enum ast_frame_type frametype
char * bframe
B channel speech sample data buffer.
static int * misdn_in_calls
void ast_channel_queue_redirecting_update(struct ast_channel *chan, const struct ast_party_redirecting *redirecting, const struct ast_set_party_redirecting *update)
Queue a redirecting update frame on a channel.
int ast_safe_sleep_conditional(struct ast_channel *chan, int ms, int(*cond)(void *), void *data)
Wait for a specified amount of time, looking for hangups and a condition argument.
#define AST_PRES_UNAVAILABLE
#define ast_mutex_init(pmutex)
#define ast_channel_trylock(chan)
static void send_digit_to_chan(struct chan_list *cl, char digit)
int cause
Q.931 Cause for disconnection code (received)
static int misdn_facility_exec(struct ast_channel *chan, const char *data)
unsigned char valid
TRUE if the name information is valid/present.
char info_dad[MISDN_MAX_NUMBER_LEN]
Current overlap dialing digits to/from INFORMATION messages.
void misdn_lib_bridge(struct misdn_bchannel *bc1, struct misdn_bchannel *bc2)
int te_choose_channel
TRUE if the TE side should choose the B channel to use.
Interface to mISDN - Config.
static char context[AST_MAX_CONTEXT]
Call Parking and Pickup API Includes code and algorithms from the Zapata library. ...
#define ast_mutex_destroy(a)
static struct robin_list * get_robin_position(char *group)
struct ast_format * format
static char * handle_cli_misdn_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * handle_cli_misdn_send_digit(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
const char * ast_channel_macrocontext(const struct ast_channel *chan)
static void update_name(struct ast_channel *tmp, int port, int c)
void ast_set_party_id_all(struct ast_set_party_id *update_id)
Set the update marker to update all information of a corresponding party id.
Redirecting information struct.
struct misdn_bchannel * bc
Associated B channel structure.
int screening
Number screening code 0=Unscreened, 1=Passed Screen, 2=Failed Screen, 3=Network Number.
#define chan_list_unref(obj, debug)
#define ASTERISK_GPL_KEY
The text the key() function should return.
#define AST_CAUSE_CALL_REJECTED
void ast_channel_priority_set(struct ast_channel *chan, int value)
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
Asterisk module definitions.
static enum mISDN_REDIRECTING_REASON ast_to_misdn_reason(const enum AST_REDIRECTING_REASON ast)
struct misdn_jb * misdn_jb_init(int size, int upper_threshold)
allocates the jb-structure and initialize the elements
static int misdn_to_ast_screen(int screening)
char * ast_print_namedgroups(struct ast_str **buf, struct ast_namedgroups *groups)
Print named call groups and named pickup groups.
int law
Companding ALaw/uLaw encoding (INFO_CODEC_ALAW / INFO_CODEC_ULAW)
int misdn_jb_empty(struct misdn_jb *jb, char *data, int len)
gets len bytes out of the jitterbuffer if available, else only the available data is returned and the...
static snd_pcm_format_t format
void(* cb_log)(int level, int port, char *tmpl,...)
int orig
Who originated the call (ORG_AST, ORG_MISDN)
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
struct FacParm fac_in
Inbound FACILITY message function type and contents.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
static int misdn_indication(struct ast_channel *ast, int cond, const void *data, size_t datalen)
int misdn_cfg_is_msn_valid(int port, char *msn)
static char * handle_cli_misdn_show_stacks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
unsigned char valid
TRUE if the number information is valid/present.
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
void ast_channel_hangupcause_hash_set(struct ast_channel *chan, const struct ast_control_pvt_cause_code *cause_code, int datalen)
Sets the HANGUPCAUSE hash and optionally the SIP_CAUSE hash on the given channel. ...
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
#define ast_custom_function_register(acf)
Register a custom function.
int overlap_dial
Enables overlap dialing for the set amount of seconds. (0 = Disabled)
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
static ast_mutex_t cl_te_lock
static int misdn_set_opt_exec(struct ast_channel *chan, const char *data)
struct FacAOCDChargingUnit chargingUnit
#define AST_BRIDGE_DTMF_CHANNEL_0
Report DTMF on channel 0.
void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
Copy the source redirecting information to the destination redirecting.
Structure for mutex and tracking information.
int count
Number of times the call has been redirected.
int noautorespond_on_setup
TRUE of we are not to respond immediately to a SETUP message. Check the dialplan first.
enum mISDN_NUMBER_PLAN number_plan
Type-of-number numbering plan.
int l3_id
Layer 3 process ID.
static void misdn_facility_ie_handler(enum event_e event, struct misdn_bchannel *bc, struct chan_list *ch)
static char * handle_cli_misdn_show_ports_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void misdn_queue_connected_line_update(struct ast_channel *ast, const struct misdn_party_id *id, enum AST_CONNECTED_LINE_UPDATE_SOURCE source, char *cid_tag)
static char * handle_cli_misdn_port_up(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static enum event_response_e cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
#define ast_mutex_unlock(a)
Configuration relating to call pickup.
#define AST_APP_ARG(name)
Define an application argument.
int early_bconnect
TRUE if the call progress indicators can indicate an inband audio message for the user to listen to...
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
static enum mISDN_NUMBER_PLAN ast_to_misdn_plan(unsigned ast_number_plan)
int nttimeout
TRUE if NT should disconnect an overlap dialing call when a timeout occurs.
struct ast_party_number number
Subscriber phone number.
int toggle_ec
TRUE if echo canceller is enabled. Value is toggled.