static int setup_signals(sd_event *event) { sigset_t signals; int result; CC_LOG_DEBUG("invoked setup_signals()\n"); assert(event); sigemptyset(&signals); sigaddset(&signals, SIGTERM); sigaddset(&signals, SIGINT); result = sigprocmask(SIG_BLOCK, &signals, NULL); if (result != 0) { CC_LOG_ERROR("unable to block signals: %s\n", strerror(result)); return -result; } result = sd_event_add_signal(event, NULL, SIGTERM, &signal_handler, event); if (result < 0) { CC_LOG_ERROR("unable to setup SIGTERM handler: %s\n", strerror(-result)); return result; } result = sd_event_add_signal(event, NULL, SIGINT, &signal_handler, event); if (result < 0) { CC_LOG_ERROR("unable to setup SIGINT handler: %s\n", strerror(-result)); return result; } return 0; }
int cc_client_Ball_new(const char *address, void *data, struct cc_client_Ball **instance) { int result; struct cc_client_Ball *ii; CC_LOG_DEBUG("invoked cc_client_Ball_new\n"); assert(address); assert(instance); ii = (struct cc_client_Ball *) calloc(1, sizeof(*ii)); if (!ii) { CC_LOG_ERROR("failed to allocate instance memory\n"); return -ENOMEM; } result = cc_instance_new(address, false, &ii->instance); if (result < 0) { CC_LOG_ERROR("failed to create instance: %s\n", strerror(-result)); goto fail; } ii->data = data; *instance = ii; return 0; fail: ii = cc_client_Ball_free(ii); return result; }
int cc_Ball_drop(struct cc_client_Ball *instance) { int result = 0; struct cc_instance *i; sd_bus_message *message = NULL; CC_LOG_DEBUG("invoked cc_Ball_drop()\n"); assert(instance); i = instance->instance; assert(i && i->backend && i->backend->bus); assert(i->service && i->path && i->interface); result = sd_bus_message_new_method_call( i->backend->bus, &message, i->service, i->path, i->interface, "drop"); if (result < 0) { CC_LOG_ERROR("unable to create message: %s\n", strerror(-result)); goto fail; } result = sd_bus_message_set_expect_reply(message, 0); if (result < 0) { CC_LOG_ERROR("unable to flag message no-reply-expected: %s\n", strerror(-result)); goto fail; } /* Setting cookie=NULL in sd_bus_send() call makes the previous one redundant */ result = sd_bus_send(i->backend->bus, message, NULL); if (result < 0) { CC_LOG_ERROR("unable to send message: %s\n", strerror(-result)); goto fail; } fail: message = sd_bus_message_unref(message); return result; }
int cc_Calculator_split_async( struct cc_client_Calculator *instance, double value, cc_Calculator_split_reply_t callback) { int result = 0; struct cc_instance *i; sd_bus_message *message = NULL; CC_LOG_DEBUG("invoked cc_Calculator_split_async()\n"); assert(instance); assert(callback); i = instance->instance; assert(i && i->backend && i->backend->bus); assert(i->service && i->path && i->interface); if (instance->split_reply_slot) { CC_LOG_ERROR("unable to call method with already pending reply\n"); return -EBUSY; } assert(!instance->split_reply_callback); result = sd_bus_message_new_method_call( i->backend->bus, &message, i->service, i->path, i->interface, "split"); if (result < 0) { CC_LOG_ERROR("unable to create message: %s\n", strerror(-result)); goto fail; } result = sd_bus_message_append(message, "d", value); if (result < 0) { CC_LOG_ERROR("unable to append message method arguments: %s\n", strerror(-result)); goto fail; } result = sd_bus_call_async( i->backend->bus, &instance->split_reply_slot, message, &cc_Calculator_split_reply_thunk, instance, CC_DBUS_ASYNC_CALL_TIMEOUT_USEC); if (result < 0) { CC_LOG_ERROR("unable to issue method call: %s\n", strerror(-result)); goto fail; } instance->split_reply_callback = callback; fail: message = sd_bus_message_unref(message); return result; }
static int cc_Smartie_hangup_thunk( CC_IGNORE_BUS_ARG sd_bus_message *m, void *userdata, sd_bus_error *error) { int result = 0; struct cc_server_Smartie *ii = (struct cc_server_Smartie *) userdata; int32_t status; CC_LOG_DEBUG("invoked cc_Smartie_hangup_thunk()\n"); assert(m); assert(ii && ii->impl); CC_LOG_DEBUG("with path='%s'\n", sd_bus_message_get_path(m)); result = sd_bus_message_read(m, ""); if (result < 0) { CC_LOG_ERROR("unable to read method parameters: %s\n", strerror(-result)); return result; } if (!ii->impl->hangup) { CC_LOG_ERROR("unsupported method invoked: %s\n", "Smartie.hangup"); sd_bus_error_set( error, SD_BUS_ERROR_NOT_SUPPORTED, "instance does not support method Smartie.hangup"); sd_bus_reply_method_error(m, error); return -ENOTSUP; } result = ii->impl->hangup(ii, &status); if (result < 0) { CC_LOG_ERROR("failed to execute method: %s\n", strerror(-result)); sd_bus_error_setf( error, SD_BUS_ERROR_FAILED, "method implementation failed with error=%d", result); sd_bus_reply_method_error(m, error); return result; } result = sd_bus_reply_method_return(m, "i", status); if (result < 0) { CC_LOG_ERROR("unable to send method reply: %s\n", strerror(-result)); return result; } /* Successful method invocation must return >0 */ return 1; }
int cc_server_Smartie_new( const char *address, const struct cc_server_Smartie_impl *impl, void *data, struct cc_server_Smartie **instance) { int result; struct cc_server_Smartie *ii; struct cc_instance *i; CC_LOG_DEBUG("invoked cc_server_Smartie_new\n"); assert(address); assert(impl); assert(instance); ii = (struct cc_server_Smartie *) calloc(1, sizeof(*ii)); if (!ii) { CC_LOG_ERROR("failed to allocate instance memory\n"); return -ENOMEM; } result = cc_instance_new(address, true, &i); if (result < 0) { CC_LOG_ERROR("failed to create instance: %s\n", strerror(-result)); goto fail; } ii->instance = i; ii->impl = impl; ii->data = data; result = sd_bus_add_object_vtable( i->backend->bus, &ii->vtable_slot, i->path, i->interface, vtable_Smartie, ii); if (result < 0) { CC_LOG_ERROR("unable to initialize instance vtable: %s\n", strerror(-result)); goto fail; } *instance = ii; return 0; fail: ii = cc_server_Smartie_free(ii); return result; }
int cc_Ball_grab(struct cc_client_Ball *instance, bool *success) { int result = 0; struct cc_instance *i; sd_bus_message *message = NULL; sd_bus_message *reply = NULL; sd_bus_error error = SD_BUS_ERROR_NULL; int success_int; CC_LOG_DEBUG("invoked cc_Ball_grab()\n"); assert(instance); i = instance->instance; assert(i && i->backend && i->backend->bus); assert(i->service && i->path && i->interface); if (instance->grab_reply_slot) { CC_LOG_ERROR("unable to call method with already pending reply\n"); return -EBUSY; } assert(!instance->grab_reply_callback); result = sd_bus_call_method( i->backend->bus, i->service, i->path, i->interface, "grab", &error, &reply, ""); if (result < 0) { CC_LOG_ERROR("unable to call method: %s\n", strerror(-result)); goto fail; } result = sd_bus_message_read(reply, "b", &success_int); if (result < 0) { CC_LOG_ERROR("unable to get reply value: %s\n", strerror(-result)); goto fail; } *success = !!success_int; CC_LOG_DEBUG("returning success=%d\n", (int) *success); fail: sd_bus_error_free(&error); reply = sd_bus_message_unref(reply); message = sd_bus_message_unref(message); return result; }
int cc_Calculator_split( struct cc_client_Calculator *instance, double value, int32_t *whole, int32_t *fraction) { int result = 0; struct cc_instance *i; sd_bus_message *message = NULL; sd_bus_message *reply = NULL; sd_bus_error error = SD_BUS_ERROR_NULL; CC_LOG_DEBUG("invoked cc_Calculator_split()\n"); assert(instance); i = instance->instance; assert(i && i->backend && i->backend->bus); assert(i->service && i->path && i->interface); if (instance->split_reply_slot) { CC_LOG_ERROR("unable to call method with already pending reply\n"); return -EBUSY; } assert(!instance->split_reply_callback); result = sd_bus_call_method( i->backend->bus, i->service, i->path, i->interface, "split", &error, &reply, "d", value); if (result < 0) { CC_LOG_ERROR("unable to call method: %s\n", strerror(-result)); goto fail; } result = sd_bus_message_read(reply, "ii", whole, fraction); if (result < 0) { CC_LOG_ERROR("unable to get reply value: %s\n", strerror(-result)); goto fail; } CC_LOG_DEBUG("returning whole=%" PRId32 ", fraction=%" PRId32 "\n", *whole, *fraction); fail: sd_bus_error_free(&error); reply = sd_bus_message_unref(reply); message = sd_bus_message_unref(message); return result; }
static int cc_Calculator_split_reply_thunk( CC_IGNORE_BUS_ARG sd_bus_message *message, void *userdata, sd_bus_error *ret_error) { int result = 0; sd_bus *bus; struct cc_client_Calculator *ii = (struct cc_client_Calculator *) userdata; int32_t whole; int32_t fraction; (void) ret_error; CC_LOG_DEBUG("invoked cc_Calculator_split_reply_thunk()\n"); assert(message); bus = sd_bus_message_get_bus(message); assert(bus); assert(ii); assert(ii->split_reply_callback); assert(ii->split_reply_slot == sd_bus_get_current_slot(bus)); result = sd_bus_message_get_errno(message); if (result != 0) { CC_LOG_ERROR("failed to receive response: %s\n", strerror(result)); goto finish; } result = sd_bus_message_read(message, "ii", &whole, &fraction); if (result < 0) { CC_LOG_ERROR("unable to get reply value: %s\n", strerror(-result)); goto finish; } CC_LOG_DEBUG("invoking callback in cc_Calculator_split_reply_thunk()\n"); CC_LOG_DEBUG("with whole=%" PRId32 ", fraction=%" PRId32 "\n", whole, fraction); ii->split_reply_callback(ii, whole, fraction); result = 1; finish: ii->split_reply_callback = NULL; ii->split_reply_slot = sd_bus_slot_unref(ii->split_reply_slot); return result; }
static int cc_Ball_grab_reply_thunk( CC_IGNORE_BUS_ARG sd_bus_message *message, void *userdata, sd_bus_error *ret_error) { int result = 0; sd_bus *bus; struct cc_client_Ball *ii = (struct cc_client_Ball *) userdata; int success_int; CC_LOG_DEBUG("invoked cc_Ball_grab_reply_thunk()\n"); assert(message); bus = sd_bus_message_get_bus(message); assert(bus); assert(ii); assert(ii->grab_reply_callback); assert(ii->grab_reply_slot == sd_bus_get_current_slot(bus)); result = sd_bus_message_get_errno(message); if (result != 0) { CC_LOG_ERROR("failed to receive response: %s\n", strerror(result)); goto finish; } result = sd_bus_message_read(message, "b", &success_int); if (result < 0) { CC_LOG_ERROR("unable to get reply value: %s\n", strerror(-result)); goto finish; } CC_LOG_DEBUG("invoking callback in cc_Ball_grab_reply_thunk()\n"); CC_LOG_DEBUG("with success=%d\n", !!success_int); ii->grab_reply_callback(ii, !!success_int); result = 1; finish: ii->grab_reply_callback = NULL; ii->grab_reply_slot = sd_bus_slot_unref(ii->grab_reply_slot); return result; }
static int signal_handler( sd_event_source *source, const struct signalfd_siginfo *signal_info, void *user_data) { sd_event *event = (sd_event *) user_data; int result; CC_LOG_DEBUG("invoked signal_handler() with signal %d\n", signal_info->ssi_signo); assert(event); assert(signal_info->ssi_signo == SIGTERM || signal_info->ssi_signo == SIGINT); result = sd_event_exit(event, 0); if (result < 0) CC_LOG_ERROR("unable to exit event loop: %s\n", strerror(-result)); return result; }
cc_of_ret find_thrmgr_rwsocket_lockfree(int sockfd, adpoll_thread_mgr_t **tmgr) { cc_of_ret status = CC_OF_OK; cc_ofrw_key_t rwkey; cc_ofrw_info_t *rwinfo = NULL; rwkey.rw_sockfd = sockfd; rwinfo = g_hash_table_lookup(cc_of_global.ofrw_htbl, &rwkey); if (rwinfo == NULL) { CC_LOG_ERROR("%s(%d): could not find rwsock %d in ofrw_htbl", __FUNCTION__, __LINE__, rwkey.rw_sockfd); return CC_OF_EHTBL; } *tmgr = rwinfo->thr_mgr_p; return status; }
void print_ofrw_htbl(void) { GHashTableIter ofrw_iter; cc_ofrw_key_t *rw_key = NULL; cc_ofrw_info_t *rw_info = NULL; gpointer rkey = NULL, rinfo = NULL; g_hash_table_iter_init(&ofrw_iter, cc_of_global.ofrw_htbl); int n; n = g_hash_table_size(cc_of_global.ofrw_htbl); CC_LOG_DEBUG("Printing ofrw Hash Table with %d entries", n); if (n) { while (g_hash_table_iter_next(&ofrw_iter, &rkey, &rinfo)) { rw_info = (cc_ofrw_info_t *)rinfo; rw_key = (cc_ofrw_key_t *)rkey; if (rw_info->thr_mgr_p == NULL) { CC_LOG_ERROR("%s(%d): no polling thread for %d", __FUNCTION__, __LINE__, rw_key->rw_sockfd); } else { CC_LOG_DEBUG("key: rw_sockfd: %d " "info: layer4_proto: %s " "info: poll thread name: %s" "info: devkey controller ip: 0x%x" "info: devkey switch ip: 0x%x" "info: devkey l4port: %d", rw_key->rw_sockfd, (rw_info->layer4_proto == TCP)? "TCP":"UDP", rw_info->thr_mgr_p->tname, rw_info->dev_key.controller_ip_addr, rw_info->dev_key.switch_ip_addr, rw_info->dev_key.controller_L4_port); } } } }
// Caller will acquire htbl locks cc_of_ret update_global_htbl_lockfree(htbl_type_e htbl_type, htbl_update_ops_e htbl_op, gpointer htbl_key, gpointer htbl_data, gboolean *new_entry) { GHashTable *cc_htbl; gpointer key, info_data; *new_entry = FALSE; guint old_count; switch(htbl_type) { case OFDEV: cc_htbl = cc_of_global.ofdev_htbl; if ((htbl_op == ADD) && (g_hash_table_contains(cc_htbl, htbl_key))) { htbl_op = UPD; /* create a new key. the insert operation will free this */ key = malloc(sizeof(cc_ofdev_key_t)); memcpy(key, htbl_key, sizeof(cc_ofdev_key_t)); info_data = malloc(sizeof(cc_ofdev_info_t)); memcpy(info_data, htbl_data, sizeof(cc_ofdev_info_t)); } break; case OFRW: cc_htbl = cc_of_global.ofrw_htbl; if ((htbl_op == ADD) && (g_hash_table_contains(cc_htbl, htbl_key))) { htbl_op = UPD; /* create a new key. the insert operation will free ths */ key = malloc(sizeof(cc_ofrw_key_t)); memcpy(key, htbl_key, sizeof(cc_ofrw_key_t)); info_data = malloc(sizeof(cc_ofrw_info_t)); memcpy(info_data, htbl_data, sizeof(cc_ofrw_info_t)); } break; case OFCHANN: cc_htbl = cc_of_global.ofchannel_htbl; if ((htbl_op == ADD) && (g_hash_table_contains(cc_htbl, htbl_key))) { /* create a new key. the insert operation will free this */ key = malloc(sizeof(cc_ofchannel_key_t)); memcpy(key, htbl_key, sizeof(cc_ofchannel_key_t)); info_data = malloc(sizeof(cc_ofchannel_info_t)); memcpy(info_data, htbl_data, sizeof(cc_ofchannel_info_t)); } break; default: CC_LOG_ERROR("%s(%d): invalid htbl type %d", __FUNCTION__, __LINE__, htbl_type); } if (htbl_op == ADD) { old_count = g_hash_table_size(cc_htbl); CC_LOG_DEBUG("%s(%d): insert operation for htbl_type %s", __FUNCTION__, __LINE__, (htbl_type == OFDEV)? "OFDEV": ((htbl_type == OFRW)?"OFRW":"OFCHANN")); if (htbl_type == OFDEV) { CC_LOG_DEBUG("%s(%d) key has controller ip 0x%x, switch ip 0x%x and port %d", __FUNCTION__, __LINE__, ((cc_ofdev_key_t *)htbl_key)->controller_ip_addr, ((cc_ofdev_key_t *)htbl_key)->switch_ip_addr, ((cc_ofdev_key_t *)htbl_key)->controller_L4_port); } else if (htbl_type == OFRW) { CC_LOG_DEBUG("%s(%d) insert key has socket %d", __FUNCTION__, __LINE__, ((cc_ofrw_key_t *)htbl_key)->rw_sockfd); CC_LOG_DEBUG("%s(%d) insert info has l4 proto %s", __FUNCTION__, __LINE__, (((cc_ofrw_info_t *)htbl_data)->layer4_proto == TCP)? "TCP":((((cc_ofrw_info_t *)htbl_data)->layer4_proto == UDP)? "UDP":"INVALID")); if (g_hash_table_contains(cc_htbl, htbl_key)) { CC_LOG_DEBUG("(%s(%d): OFRW htbl already contains %d", __FUNCTION__, __LINE__, ((cc_ofrw_key_t *)htbl_key)->rw_sockfd); } } else if (htbl_type == OFCHANN) { CC_LOG_DEBUG("%s(%d) ofchannel key dp/aux %lu/%hu", __FUNCTION__, __LINE__, ((cc_ofchannel_key_t *)htbl_key)->dp_id, ((cc_ofchannel_key_t *)htbl_key)->aux_id); } g_hash_table_insert(cc_htbl, htbl_key, htbl_data); if (htbl_type == OFDEV) { } else if (htbl_type == OFRW) { gpointer rwht_key = NULL, rwht_info = NULL; if (g_hash_table_contains(cc_htbl, htbl_key)) { CC_LOG_DEBUG("(%s(%d): OFRW htbl contains %d", __FUNCTION__, __LINE__, ((cc_ofrw_key_t *)htbl_key)->rw_sockfd); } CC_LOG_DEBUG("OFRW htbl size after insert of %d: %d", ((cc_ofrw_key_t *)htbl_key)->rw_sockfd, g_hash_table_size(cc_htbl)); if (g_hash_table_lookup_extended(cc_of_global.ofrw_htbl, htbl_key, &rwht_key, &rwht_info) == FALSE) { CC_LOG_DEBUG("extended lookup failed"); } else { cc_ofrw_key_t *rw_key = NULL; cc_ofrw_info_t *rw_info = NULL; rw_key = (cc_ofrw_key_t *)rwht_key; rw_info = (cc_ofrw_info_t *)rwht_info; CC_LOG_DEBUG("extended lookup passed"); CC_LOG_DEBUG("key: rw_sockfd: %d " "info: layer4_proto: %s " "info: poll thread name: %s" "info: devkey controller ip: 0x%x" "info: devkey switch ip: 0x%x" "info: devkey l4port: %d", rw_key->rw_sockfd, (rw_info->layer4_proto == TCP)? "TCP":"UDP", rw_info->thr_mgr_p->tname, rw_info->dev_key.controller_ip_addr, rw_info->dev_key.switch_ip_addr, rw_info->dev_key.controller_L4_port); } CC_LOG_DEBUG("%s(%d) key has socket %d", __FUNCTION__, __LINE__, ((cc_ofrw_key_t *)htbl_key)->rw_sockfd); } if (g_hash_table_size(cc_htbl) > old_count) { *new_entry = TRUE; } } else if (htbl_op == DEL) { CC_LOG_DEBUG("%s(%d).. HTBL DEL ", __FUNCTION__, __LINE__); if (g_hash_table_contains(cc_htbl, htbl_key)) { CC_LOG_DEBUG("%s(%d) DEL operation found entry", __FUNCTION__, __LINE__); } if (g_hash_table_remove(cc_htbl, htbl_key) == FALSE) { CC_LOG_DEBUG("%s(%d) DEL unsuccessful", __FUNCTION__, __LINE__); return CC_OF_EHTBL; } } else if (htbl_op == UPD) { old_count = g_hash_table_size(cc_htbl); CC_LOG_DEBUG("%s(%d): replace existing entry operation", __FUNCTION__, __LINE__); if (htbl_type == OFDEV) { CC_LOG_DEBUG("%s(%d) key has controller ip 0x%x, switch ip 0x%x and port %d", __FUNCTION__, __LINE__, ((cc_ofdev_key_t *)key)->controller_ip_addr, ((cc_ofdev_key_t *)key)->switch_ip_addr, ((cc_ofdev_key_t *)key)->controller_L4_port); } g_hash_table_insert(cc_htbl, key, info_data); if (htbl_type == OFDEV) { } else if (htbl_type == OFCHANN) { } else if (htbl_type == OFRW) { gpointer rwht_key = NULL, rwht_info = NULL; if (g_hash_table_contains(cc_htbl, htbl_key)) { CC_LOG_DEBUG("(%s(%d): OFRW htbl contains %d", __FUNCTION__, __LINE__, ((cc_ofrw_key_t *)htbl_key)->rw_sockfd); } CC_LOG_DEBUG("OFRW htbl size after insert of %d: %d", ((cc_ofrw_key_t *)htbl_key)->rw_sockfd, g_hash_table_size(cc_htbl)); if (g_hash_table_lookup_extended(cc_of_global.ofrw_htbl, htbl_key, &rwht_key, &rwht_info) == FALSE) { CC_LOG_DEBUG("extended lookup failed"); } else { cc_ofrw_key_t *rw_key = NULL; cc_ofrw_info_t *rw_info = NULL; rw_key = (cc_ofrw_key_t *)rwht_key; rw_info = (cc_ofrw_info_t *)rwht_info; CC_LOG_DEBUG("extended lookup passed"); CC_LOG_DEBUG("key: rw_sockfd: %d " "info: layer4_proto: %s " "info: poll thread name: %s" "info: devkey controller ip: 0x%x" "info: devkey switch ip: 0x%x" "info: devkey l4port: %d", rw_key->rw_sockfd, (rw_info->layer4_proto == TCP)? "TCP":"UDP", rw_info->thr_mgr_p->tname, rw_info->dev_key.controller_ip_addr, rw_info->dev_key.switch_ip_addr, rw_info->dev_key.controller_L4_port); } } if (g_hash_table_size(cc_htbl) > old_count) { *new_entry = TRUE; } } return CC_OF_OK; }