FibaroPlug() { logger = zlog_create(stdout, Critical); zway = NULL; #ifdef _WINDOWS ZWError r = zway_init(&zway, ZSTR("COM3"), NULL, NULL, NULL, NULL, logger); #endif #ifdef __MACH__ ZWError r = zway_init(&zway, ZSTR("/dev/cu.SLAB_USBtoUART"), NULL, NULL, NULL, NULL, logger); #endif #ifdef __linux__ //Aus der Doku: //ZWEXPORT ZWError zway_init(ZWay *pzway, ZWCSTR port, ZWCSTR config_folder, ZWCSTR translations_folder, ZWCSTR zddx_folder, ZWCSTR name, ZWLog logger); ZWError r = zway_init(&zway, ZSTR("/dev/ttyAMA0"), ZSTR("/opt/z-way-server/config/"), ZSTR("/opt/z-way-server/translations/"), ZSTR("/opt/z-way-server/ZDDX/"), NULL, logger); zway_log(zway, Debug, ZSTR("ZWAY device successfully created")); #endif if (r != NoError) { std::cout << "Failed to init ZWay\n"; exit(EXIT_FAILURE); } r = zway_start(zway, print_zway_terminated, NULL); if (r != NoError) { std::cout << "Failed to start ZWay\n"; exit(EXIT_FAILURE); } r = zway_discover(zway); if (r != NoError) { std::cout << "Failed to negotiate with Z-Wave stick\n"; exit(EXIT_FAILURE); } }
int main(int argc, const char * argv[]) { ZWLog logger = zlog_create(stdout, Debug); // ZWLog logger = NULL; ZWay zway = NULL; #ifdef _WINDOWS ZWError r = zway_init(&zway, ZSTR("COM3"), NULL, NULL, NULL, NULL, logger); #endif #ifdef __MACH__ ZWError r = zway_init(&zway, ZSTR("/dev/cu.SLAB_USBtoUART"), NULL, NULL, NULL, NULL, logger); #endif #ifdef __linux__ // ZWError r = zway_init(&zway, ZSTR("/dev/ttyUSB0"), NULL, NULL, NULL, NULL, logger); ZWError r = zway_init(&zway, ZSTR("/dev/ttyAMA0"), NULL, NULL, NULL, NULL, logger); #endif if (r != NoError) { printf("\n initError \n"); zway_log_error(zway, Critical, "Failed to init ZWay", r); return -1; } printf("\ncallback\n"); zway_device_add_callback(zway, DeviceAdded | DeviceRemoved | InstanceAdded | InstanceRemoved | CommandAdded | CommandRemoved, print_D_I_CC_event, NULL); printf("\nstart\n"); r = zway_start(zway, print_zway_terminated, NULL); if (r != NoError) { printf("\nstartError\n"); zway_log_error(zway, Critical, "Failed to start ZWay", r); return -1; } r = zway_discover(zway); if (r != NoError) { zway_log_error(zway, Critical, "Failed to negotiate with Z-Wave stick", r); return -1; } pin_init(); printf("\ndowork\n"); // Application code int code = do_work(zway); //int code =0; r = zway_stop(zway); zway_terminate(&zway); return code; }
static void destroy_kv_store_val(void* _val) { int_str_t *val = (int_str_t *)_val; if (val->is_str && !ZSTR(val->s)) shm_free(val->s.s); shm_free(val); }
void print_basic_holder(const ZWay zway, ZWDataChangeType type, ZDataHolder data) { int int_val; zdata_get_integer(data, &int_val); zway_log(zway, Debug, ZSTR("Basic set value = %i"), int_val); int_val2 = int_val; printf("print, int_val : %d \n", int_val2); }
int main(int argc, const char *argv[]) { ZWLog logger = zlog_create(stdout, Silent); ZWay zway = NULL; #ifdef _WINDOWS ZWError r = zway_init(&zway, ZSTR("COM3"), NULL, NULL, NULL, NULL, logger); #endif #ifdef __MACH__ ZWError r = zway_init(&zway, ZSTR("/dev/cu.SLAB_USBtoUART"), NULL, NULL, NULL, NULL, logger); #endif #ifdef __linux__ ZWError r = zway_init(&zway, ZSTR("/dev/ttyAMA0"), ZSTR("/opt/z-way-server/config/"), ZSTR("/opt/z-way-server/translations/"), ZSTR("/opt/z-way-server/ZDDX/"), NULL, logger); zway_log(zway, Debug, ZSTR("ZWAY device successfully created")); #endif if (r != NoError) { zway_log_error(zway, Critical, "Failed to init ZWay", r); return -1; } r = zway_start(zway, print_zway_terminated, NULL); if (r != NoError) { zway_log_error(zway, Critical, "Failed to start ZWay", r); return -1; } r = zway_discover(zway); if (r != NoError) { zway_log_error(zway, Critical, "Failed to negotiate with Z-Wave stick", r); return -1; } // Application code do_work(zway); r = zway_stop(zway); zway_terminate(&zway); return 0; }
void print_D_I_CC_event(const ZWay zway, ZWDeviceChangeType type, ZWBYTE node_id, ZWBYTE instance_id, ZWBYTE command_id, void *arg) { switch (type) { case DeviceAdded: zway_log(zway, Information, ZSTR("New device added: %i"), node_id); break; case DeviceRemoved: zway_log(zway, Information, ZSTR("Device removed: %i"), node_id); break; case InstanceAdded: zway_log(zway, Information, ZSTR("New instance added to device %i: %i"), node_id, instance_id); break; case InstanceRemoved: zway_log(zway, Information, ZSTR("Instance removed from device %i: %i"), node_id, instance_id); break; case CommandAdded: zway_log(zway, Information, ZSTR("New Command Class added to device %i:%i: %i"), node_id, instance_id, command_id); break; case CommandRemoved: zway_log(zway, Information, ZSTR("Command Class removed from device %i:%i: %i"), node_id, instance_id, command_id); break; } }
int cl_get_my_sip_addr(int cluster_id, str *out_addr) { cluster_info_t *cl; int rc; if (!cl_list_lock) { LM_ERR("cluster shutdown\n"); memset(out_addr, 0, sizeof *out_addr); return -1; } lock_start_read(cl_list_lock); cl = get_cluster_by_id(cluster_id); if (!cl) { LM_ERR("unknown cluster id: %d\n", cluster_id); lock_stop_read(cl_list_lock); memset(out_addr, 0, sizeof *out_addr); return -1; } lock_get(cl->current_node->lock); if (ZSTR(cl->current_node->sip_addr)) { memset(out_addr, 0, sizeof *out_addr); rc = 0; } else { if (pkg_str_dup(out_addr, &cl->current_node->sip_addr) != 0) { LM_ERR("oom\n"); memset(out_addr, 0, sizeof *out_addr); rc = -1; } else { rc = 0; } } lock_release(cl->current_node->lock); lock_stop_read(cl_list_lock); return rc; }
void print_zway_terminated(ZWay zway, void *arg) { zway_log(zway, Information, ZSTR("Z-Way terminated")); }
void appendHandlers() { char cmd, cc_cmd, holder_root; ZWBYTE dev, inst, cc, cc_val; char data_path[256]; char cmd_buffer[256]; ZWBOOL was_idle = FALSE; ZWBOOL basic_level_attached = FALSE; int running = TRUE; if (!zway_is_running(zway)) { running = FALSE; break; } while (true) { if (!zway_is_idle(zway)) { sleep_ms(10); break; } } ZDataHolder basic_level_holder_power, basic_level_holder_meter; ZWDevicesList list = zway_devices_list(zway); if (list != NULL) { int i = 0; while (list[i]) { zdata_acquire_lock(ZDataRoot(zway)); if (list[i] > 1) { zway_log(zway, Debug, ZSTR("Search data holder for device %i"), list[i]); basic_level_holder_meter = zway_find_device_instance_cc_data(zway, list[i], 0, 0x31, "4.val"); if (basic_level_holder_meter) { basic_level_attached = (zdata_add_callback(basic_level_holder_meter, (ZDataChangeCallback) handle_watt_value, FALSE, NULL) == NoError); if (basic_level_attached) { zway_log(zway, Critical, ZSTR("Basic.data.level holder handler attached to device %i instance 0"), list[i]); } else { zway_log(zway, Critical, ZSTR("Could not attache handler to device %i"), list[i]); } } basic_level_holder_power = zway_find_device_instance_cc_data(zway, list[i], 0, 0x32, "0.val"); if (basic_level_holder_power) { basic_level_attached = (zdata_add_callback(basic_level_holder_power, (ZDataChangeCallback) handle_power_value, FALSE, NULL) == NoError); if (basic_level_attached) { zway_log(zway, Critical, ZSTR("Basic.data.level holder handler attached to device %i instance 0"), list[i]); } else { zway_log(zway, Critical, ZSTR("Could not attache handler to device %i"), list[i]); } } ZDataHolder dataHolder = zway_find_device_instance_cc_data(zway, list[i], 0, 0x25, "level"); if (dataHolder) { zdata_add_callback(dataHolder, (ZDataChangeCallback) dataChangeCallback, TRUE, NULL); } } zdata_release_lock(ZDataRoot(zway)); i++; } basic_level_attached = TRUE; } }
int do_work(ZWay zway) { print_help(); char cmd, cc_cmd, holder_root; ZWBYTE dev, inst, cc, cc_val, nconv; char data_path[256]; char cmd_buffer[256]; ZWBOOL was_idle = FALSE; ZWBOOL basic_level_attached = FALSE; int skip = 0; int running = TRUE; int level = 0; /* while(1){ digitalWrite(LED1,1); delay(500); digitalWrite(LED1,0); delay(500); }*/ while (running) { /* printf("\n\n\n"); zdata_acquire_lock(ZDataRoot(zway)); level = get_data(zway, zway_find_device_instance_cc_data(zway, '2', '0', 32, 'level')); zdata_release_lock(ZDataRoot(zway));*/ /* zdata_acquire_lock(ZDataRoot(zway)); level = get_data(zway, zway_find_device_data(zway, '1', 'level')); zdata_release_lock(ZDataRoot(zway)); */ printf("data ::::::: %d", int_val2); //zdata_add_callback(zway_find_device_instance_cc_data(zway,1,0,32,"mylevel"),[ZDataChangeCallback] callback, FALSE,[void*]arg); printf("\nLOG,while1\n"); if (!zway_is_running(zway)) //this is almost can not be execute { running = FALSE; break; } printf("\nLOG,while2\n"); if (!zway_is_idle(zway)) //maybe wait for { printf("\nLOG, sleep\n"); sleep_ms(10); continue; } skip = 0; /* printf("\nLOG,while3\n"); if (!basic_level_attached) { printf("\nLOG,basic level start\n"); ZDataHolder basic_level_holder; zdata_acquire_lock(ZDataRoot(zway)); basic_level_holder = zway_find_device_instance_cc_data(zway, 8, 0, 0x20, "mylevel"); // basic_level_holder = zway_find_device_instance_cc_data(zway, 8, 0, 0x26, "level"); if (basic_level_holder) { printf("\nLOG,basic level holder\n"); basic_level_attached = (zdata_add_callback(basic_level_holder, (ZDataChangeCallback) print_basic_holder, FALSE, NULL) == NoError); if (basic_level_attached){ zway_log(zway, Debug, ZSTR("Basic.data.mylevel holder handler attached to device 8 instance 0")); printf("\nLOG,basic level attatched\n"); } } zdata_release_lock(ZDataRoot(zway)); }*/ printf("\nLOG,while4\n"); if (!basic_level_attached) { printf("\nLOG,basic level start\n"); ZDataHolder basic_level_holder; zdata_acquire_lock(ZDataRoot(zway)); // basic_level_holder = zway_find_device_instance_cc_data(zway, 8, 0, 0x20, "mylevel"); basic_level_holder = zway_find_device_instance_cc_data(zway, 2, 0, 32, "level"); if (basic_level_holder) { printf("\nLOG,basic level holder\n"); basic_level_attached = (zdata_add_callback(basic_level_holder, (ZDataChangeCallback) print_basic_holder, FALSE, NULL) == NoError); if (basic_level_attached) { zway_log(zway, Debug, ZSTR( "Basic.data.mylevel holder handler attached to device 8 instance 0")); printf("\nLOG,basic level attatched\n"); pthread_create(&pthread, NULL, observer_function, NULL); pthread_detach(pthread); } } zdata_release_lock(ZDataRoot(zway)); } printf("> "); fgets(cmd_buffer, 255, stdin); was_idle = FALSE; nconv = sscanf(cmd_buffer, "%c %*s", &cmd); printf("nconv : %hhd", &nconv); if (nconv > 0) { switch (cmd) { case 'h': print_help(); break; case 'd': nconv = sscanf(cmd_buffer, "%c %c", &cmd, &holder_root); if (nconv > 1) { switch (holder_root) { case 'r': nconv = sscanf(cmd_buffer, "%c %c %s", &cmd, &holder_root, data_path); if (nconv >= 2) { if (nconv == 2) { data_path[0] = '.'; data_path[1] = '\0'; } zdata_acquire_lock(ZDataRoot(zway)); dump_data(zway, zway_find_controller_data(zway, data_path)); zdata_release_lock(ZDataRoot(zway)); } break; case 'd': nconv = sscanf(cmd_buffer, "%c %c %hhd %s", &cmd, &holder_root, &dev, data_path); if (nconv >= 3) { if (nconv == 3) { data_path[0] = '.'; data_path[1] = '\0'; } zdata_acquire_lock(ZDataRoot(zway)); dump_data(zway, zway_find_device_data(zway, dev, data_path)); zdata_release_lock(ZDataRoot(zway)); } break; case 'i': nconv = sscanf(cmd_buffer, "%c %c %hhd %hhd %s", &cmd, &holder_root, &dev, &inst, data_path); if (nconv >= 4) { if (nconv == 4) { data_path[0] = '.'; data_path[1] = '\0'; } zdata_acquire_lock(ZDataRoot(zway)); dump_data(zway, zway_find_device_instance_data(zway, dev, inst, data_path)); zdata_release_lock(ZDataRoot(zway)); } break; case 'c': nconv = sscanf(cmd_buffer, "%c %c %hhd %hhd %hhd %s", &cmd, &holder_root, &dev, &inst, &cc, data_path); if (nconv >= 5) { if (nconv == 5) { data_path[0] = '.'; data_path[1] = '\0'; } zdata_acquire_lock(ZDataRoot(zway)); dump_data(zway, zway_find_device_instance_cc_data(zway, dev, inst, cc, data_path)); zdata_release_lock(ZDataRoot(zway)); } break; } } break; case 's': nconv = sscanf(cmd_buffer, "%c %hhd %hhd %hhd %c %hhd", &cmd, &dev, &inst, &cc, &cc_cmd, &cc_val); printf("nconv : %hhd \n", &nconv); /* if (nconv == 6 && cmd == 's' && cc == 0x20 && cc_cmd == 's') { printf("nconv2 : %hhd \n",&nconv); printf("if gogo111111111111111111111111111111111111111111111111111111111111111111\n"); zdata_acquire_lock(ZDataRoot(zway)); zway_cc_switch_multilevel_set(zway, dev, inst, cc_val, 0x01 ,NULL ,NULL,0); zdata_release_lock(ZDataRoot(zway)); } else if (nconv == 5 && cmd == 's' && cc == 0x20 && cc_cmd == 'g') { printf("elseif gogo\n"); zdata_acquire_lock(ZDataRoot(zway)); zway_cc_switch_multilevel_get(zway, dev, inst,NULL,NULL,0); zdata_release_lock(ZDataRoot(zway)); } */ if (nconv == 6 && cmd == 's' && cc == 0x20 && cc_cmd == 's') { printf("nconv2 : %hhd \n", &nconv); printf( "if gogo111111111111111111111111111111111111111111111111111111111111111111\n"); zdata_acquire_lock(ZDataRoot(zway)); zway_cc_basic_set(zway, dev, inst, cc_val, NULL, NULL, NULL); zdata_release_lock(ZDataRoot(zway)); } else if (nconv == 5 && cmd == 's' && cc == 0x20 && cc_cmd == 'g') { printf("elseif gogo\n"); zdata_acquire_lock(ZDataRoot(zway)); zway_cc_basic_get(zway, dev, inst, NULL, NULL, NULL); zdata_release_lock(ZDataRoot(zway)); } else if (nconv == 6 && cmd == 's' && cc == 0x26 && cc_cmd == 's') { printf("nconv2 : %hhd \n", &nconv); printf( "if gogo333333333333333333333333333333333333333333333333333333333\n"); zdata_acquire_lock(ZDataRoot(zway)); zway_cc_switch_multilevel_set(zway, dev, inst, cc_val, 0x01, NULL, NULL, 0); zdata_release_lock(ZDataRoot(zway)); } break; case 'n': nconv = sscanf(cmd_buffer, "%c %hhd", &cmd, &dev); if (nconv == 2) zway_fc_request_node_information(zway, dev, NULL, NULL, NULL); break; case 'm': test_memory(zway); break; case 'a': zway_fc_add_node_to_network(zway, TRUE, TRUE, NULL, NULL, NULL); break; case 'A': zway_fc_add_node_to_network(zway, FALSE, TRUE, NULL, NULL, NULL); break; case 'e': zway_fc_remove_node_from_network(zway, TRUE, TRUE, NULL, NULL, NULL); break; case 'x': running = FALSE; break; case 'S': test_save(zway); break; case 'R': test_restore(zway); break; case 'q': // digitalWrite(LED1, 1); break; case 'w': // digitalWrite(LED1, 0); break; case 'l': nconv = sscanf(cmd_buffer, "%c %hhd %hhd", &cmd, &dev, &inst); switch (nconv) { case 1: { ZWDevicesList list = zway_devices_list(zway); if (list != NULL) { int i = 0; printf("Devices list: "); while (list[i]) { printf("%i ", list[i]); i++; } zway_devices_list_free(list); printf("\n"); } else printf("Error happened requesting devices list\n"); } break; case 2: { ZWInstancesList list = zway_instances_list(zway, dev); if (list != NULL) { int i = 0; printf("Instances list for device %i: ", dev); while (list[i]) { printf("%i ", list[i]); i++; } zway_instances_list_free(list); printf("\n"); } else printf("Error happened requesting instances list\n"); } break; case 3: { ZWCommandClassesList list = zway_command_classes_list(zway, dev, inst); if (list != NULL) { int i = 0; printf( "Command Classes list for device %i instance %i: ", dev, inst); while (list[i]) { printf("%02x ", list[i]); i++; } zway_command_classes_list_free(list); printf("\n"); } else printf( "Error happened requesting command classes list\n"); } break; } break; } } } return 0; }
void dump_data(const ZWay zway, ZDataHolder data) { char *path = zdata_get_path(data); ZWDataType type; zdata_get_type(data, &type); ZWBOOL bool_val; int int_val; float float_val; ZWCSTR str_val; const ZWBYTE *binary; const int *int_arr; const float *float_arr; const ZWCSTR *str_arr; size_t len, i; switch (type) { case Empty: zway_log(zway, Debug, ZSTR("DATA %s = Empty"), path); break; case Boolean: zdata_get_boolean(data, &bool_val); if (bool_val) zway_log(zway, Debug, ZSTR("DATA %s = True"), path); else zway_log(zway, Debug, ZSTR("DATA %s = False"), path); break; case Integer: zdata_get_integer(data, &int_val); zway_log(zway, Debug, ZSTR("DATA %s = %d (0x%08x)"), path, int_val, int_val); break; case Float: zdata_get_float(data, &float_val); zway_log(zway, Debug, ZSTR("DATA %s = %f"), path, float_val); break; case String: zdata_get_string(data, &str_val); zway_log(zway, Debug, ZSTR("DATA %s = \"%s\""), path, str_val); break; case Binary: zdata_get_binary(data, &binary, &len); zway_log(zway, Debug, ZSTR("DATA %s = byte[%d]"), path, len); zway_dump(zway, Debug, ZSTR(" "), len, binary); break; case ArrayOfInteger: zdata_get_integer_array(data, &int_arr, &len); zway_log(zway, Debug, ZSTR("DATA %s = int[%d]"), path, len); for (i = 0; i < len; i++) zway_log(zway, Debug, ZSTR(" [%02d] %d"), i, int_arr[i]); break; case ArrayOfFloat: zdata_get_float_array(data, &float_arr, &len); zway_log(zway, Debug, ZSTR("DATA %s = float[%d]"), path, len); for (i = 0; i < len; i++) zway_log(zway, Debug, ZSTR(" [%02d] %f"), i, float_arr[i]); break; case ArrayOfString: zdata_get_string_array(data, &str_arr, &len); zway_log(zway, Debug, ZSTR("DATA %s = string[%d]"), path, len); for (i = 0; i < len; i++) zway_log(zway, Debug, ZSTR(" [%02d] \"%s\""), i, str_arr[i]); break; } free(path); ZDataIterator child = zdata_first_child(data); while (child != NULL) { path = zdata_get_path(child->data); zway_log(zway, Debug, ZSTR("CHILD %s"), path); free(path); child = zdata_next_child(child); } //printf("intval : %d \n", int_val); }
void replicate_ucontact_update(urecord_t *r, ucontact_t *ct) { str st; int rc; bin_packet_t packet; if (bin_init(&packet, &contact_repl_cap, REPL_UCONTACT_UPDATE, BIN_VERSION, 0) != 0) { LM_ERR("failed to replicate this event\n"); return; } bin_push_str(&packet, r->domain); bin_push_str(&packet, &r->aor); bin_push_str(&packet, &ct->c); bin_push_str(&packet, &ct->callid); bin_push_str(&packet, &ct->user_agent); bin_push_str(&packet, &ct->path); bin_push_str(&packet, &ct->attr); bin_push_str(&packet, &ct->received); bin_push_str(&packet, &ct->instance); st.s = (char *) &ct->expires; st.len = sizeof ct->expires; bin_push_str(&packet, &st); st.s = (char *) &ct->q; st.len = sizeof ct->q; bin_push_str(&packet, &st); bin_push_str(&packet, ct->sock?&ct->sock->sock_str:NULL); bin_push_int(&packet, ct->cseq); bin_push_int(&packet, ct->flags); bin_push_int(&packet, ct->cflags); bin_push_int(&packet, ct->methods); st.s = (char *)&ct->last_modified; st.len = sizeof ct->last_modified; bin_push_str(&packet, &st); st = store_serialize(ct->kv_storage); if (ZSTR(st)) LM_ERR("oom\n"); bin_push_str(&packet, &st); store_free_buffer(&st); if (cluster_mode == CM_FEDERATION_CACHEDB) rc = clusterer_api.send_all_having(&packet, location_cluster, NODE_CMP_EQ_SIP_ADDR); else rc = clusterer_api.send_all(&packet, location_cluster); switch (rc) { case CLUSTERER_CURR_DISABLED: LM_INFO("Current node is disabled in cluster: %d\n", location_cluster); goto error; case CLUSTERER_DEST_DOWN: LM_INFO("All destinations in cluster: %d are down or probing\n", location_cluster); goto error; case CLUSTERER_SEND_ERR: LM_ERR("Error sending in cluster: %d\n", location_cluster); goto error; } bin_free_packet(&packet); return; error: LM_ERR("replicate ucontact update failed\n"); bin_free_packet(&packet); }
int w_do_acc_3(struct sip_msg* msg, char* type_p, char* flags_p, char* table_p) { unsigned long long type=0, flags=0; unsigned long long flag_mask; acc_ctx_t* acc_ctx; acc_type_param_t* acc_param; str in; str table_name; int tmcb_types; int is_invite; if (type_p == NULL) { LM_ERR("accounting type is mandatory!\n"); return -1; } if (!msg) { LM_ERR("no SIP message\n"); return -1; } if (skip_cancel(msg)) { LM_WARN("do_accounting() called on CANCEL but 'report_cancels' modparam" " not set - no accounting will be done for this transaction!\n"); return 1; } acc_param = (acc_type_param_t *)type_p; if (acc_param->t == DO_ACC_PARAM_TYPE_VALUE) { type = acc_param->u.ival; } else { if (pv_printf_s(msg, acc_param->u.pval, &in) < 0) { LM_ERR("failed to fetch type value!\n"); return -1; } if ((type=do_acc_parse(&in, do_acc_type_parser)) == DO_ACC_ERR) { LM_ERR("Invalid expression <%.*s> for acc type!\n", in.len, in.s); return -1; } } if (table_p != NULL) { if (fixup_get_svalue(msg, (gparam_p)table_p, &table_name) < 0) { LM_ERR("failed to fetch table name!\n"); return -1; } } if (flags_p != NULL) { flags= *(unsigned long long*)flags_p; } flag_mask = type + type * flags; if (is_cdr_acc_on(flag_mask)) { /* setting this flag will allow us to register everything * that is needed for CDR accounting only once */ set_cdr_values_registered(flag_mask); } /* is it the first time when the function was called ? */ acc_ctx = try_fetch_ctx(); /* we go in here only if do_accounting function was called before; * if accounting context is null or it's created but flags value is * 0(meaning that context was created from somewhere else but do_accounting * wasn't called) then we need to jump over this and register * all the callbacks we need */ if (acc_ctx != NULL && acc_ctx->flags != 0) { /* do_accounting already called once */ /* first check if the accounting table changed */ if (is_db_acc_on(flag_mask) && (table_p != NULL || ZSTR(acc_ctx->acc_table))) { if (table_p == NULL) { table_name = db_table_acc; } if (store_acc_table( acc_ctx, &table_name) < 0) { LM_ERR("failed to store acc table!\n"); return -1; } } if (!cdr_values_registered(acc_ctx->flags) && cdr_values_registered(flag_mask)) { /* CDR support requested for the first time, we need to create * the dialog support, if an initial INVITE */ if (!has_totag(msg)) { acc_ctx->created = time(NULL); if (msg->REQ_METHOD == METHOD_INVITE && create_acc_dlg(msg) < 0) { LM_ERR("cannot use dialog accounting module\n"); return -1; } } } /* if it's the first time the missed calls flag was used register the callback */ if (is_mc_acc_on(flag_mask) && !failure_cb_registered(acc_ctx->flags)) { acc_ref(acc_ctx); if (tmb.register_tmcb( msg, 0, TMCB_ON_FAILURE, tmcb_func, acc_ctx, unref_acc_ctx)<=0) { LM_ERR("cannot register missed calls callback\n"); acc_unref(acc_ctx); return -1; } /* don't allow the callback to be registered agian in the future */ set_failure_cb_registered(acc_ctx->flags); } acc_ctx->flags |= flag_mask; return 1; } /* initialize accounting context if not created before */ if (acc_ctx == NULL && init_acc_ctx(&acc_ctx) < 0) { LM_ERR("failed to create accounting context!\n"); return -1; } /* move acc table in context if we have database accounting */ if (is_db_acc_on(flag_mask)) { if (table_p == NULL) { table_name = db_table_acc; } if (store_acc_table( acc_ctx, &table_name) < 0) { LM_ERR("failed to store acc table!\n"); return -1; } } /* * the first bit in each byte will just tell that we want that type of * accounting * next bits will tell extra options for that type of accounting * so we keep the first bits in each byte and on the following positions * next flags */ acc_ctx->flags = flag_mask; if (is_acc_on(acc_ctx->flags) || is_mc_acc_on(acc_ctx->flags)) { /* do some parsing in advance */ if (acc_preparse_req(msg)<0) return -1; is_invite = (msg->REQ_METHOD==METHOD_INVITE)?1:0; /* install additional handlers */ tmcb_types = /* report on completed transactions */ TMCB_RESPONSE_IN|TMCB_RESPONSE_OUT; if (is_invite && is_mc_acc_on(acc_ctx->flags)) { /* register it manually; see explanation below * get incoming replies ready for processing */ /* TMCB_RESPONSE_OUT | */ /* report on missed calls */ tmcb_types |= TMCB_ON_FAILURE; /* the flag will help on further do_accounting calls to know * not to register the callback twice */ set_failure_cb_registered(acc_ctx->flags); } /* if cdr accounting is enabled */ if (is_cdr_acc_on(acc_ctx->flags) && !has_totag(msg)) { acc_ctx->created = time(NULL); if (is_invite && create_acc_dlg(msg) < 0) { LM_ERR("cannot use dialog accounting module\n"); return -1; } } acc_ref(acc_ctx); if (tmb.register_tmcb( msg, 0, tmcb_types, tmcb_func, acc_ctx, unref_acc_ctx)<=0) { LM_ERR("cannot register additional callbacks\n"); acc_unref(acc_ctx); return -1; } /* if required, determine request direction */ if( detect_direction && !rrb.is_direction(msg,RR_FLOW_UPSTREAM) ) { LM_DBG("detected an UPSTREAM req -> flaging it\n"); msg->msg_flags |= FL_REQ_UPSTREAM; } } return 1; }