static DBusMessage *profile_new_connection(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessageIter args; const char *device; int fd; GIOChannel *io; dbus_message_iter_init(msg, &args); if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) return invalid_args(msg); dbus_message_iter_get_basic(&args, &device); dbus_message_iter_next(&args); if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_UNIX_FD) return invalid_args(msg); dbus_message_iter_get_basic(&args, &fd); io = g_io_channel_unix_new(fd); if (io == NULL) return invalid_args(msg); DBG("device %s", device); connect_event(io, NULL, data); return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); }
static DBusMessage *unregister_agent(DBusConnection *conn, DBusMessage *msg, void *data) { const char *path, *sender; if (!agent) return agent_does_not_exist(msg); if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) return invalid_args(msg); if (strcmp(agent->path, path) != 0) return agent_does_not_exist(msg); sender = dbus_message_get_sender(msg); if (strcmp(agent->bus_name, sender) != 0) return not_authorized(msg); g_dbus_remove_watch(conn, agent->watch_id); agent_free(agent); agent = NULL; DBG("Agent unregistered"); return dbus_message_new_method_return(msg); }
static DBusMessage *activate_service(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessage *reply; const char *pattern; struct service *service; const char *busname = "org.bluez"; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, DBUS_TYPE_INVALID)) return invalid_args(msg); service = search_service(pattern); if (!service) return no_such_service(msg); reply = dbus_message_new_method_return(msg); if (!reply) return NULL; dbus_message_append_args(reply, DBUS_TYPE_STRING, &busname, DBUS_TYPE_INVALID); return reply; }
static DBusMessage *register_agent(DBusConnection *conn, DBusMessage *msg, void *data) { const char *path, *sender; if (agent) return agent_already_exists(msg); if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) return invalid_args(msg); sender = dbus_message_get_sender(msg); agent = g_new0(struct agent, 1); agent->bus_name = g_strdup(sender); agent->path = g_strdup(path); agent->watch_id = g_dbus_add_disconnect_watch(conn, sender, agent_disconnected, NULL, NULL); DBG("Agent registered"); return dbus_message_new_method_return(msg); }
static DBusMessage *card_status(DBusConnection *conn, DBusMessage *msg, void *data) { dbus_uint32_t status; DBG("status %d", sim_card_conn_status); if (sim_card_conn_status != SIM_CONNECTED) return g_dbus_create_error(msg, "org.bluez.Error.Failed", "Can't change msg size when not connected."); if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &status, DBUS_TYPE_INVALID)) return invalid_args(msg); if (status) { if (sim_card_conn_status == SIM_MISSING) { sim_card_conn_status = SIM_CONNECTED; sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_INSERTED); } } else { sim_card_conn_status = SIM_MISSING; sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_REMOVED); } DBG("Card status changed to %d", status); return dbus_message_new_method_return(msg); }
static DBusMessage *battery_level(DBusConnection *conn, DBusMessage *msg, void *data) { dbus_uint32_t level; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &level, DBUS_TYPE_INVALID)) return invalid_args(msg); if (level > 5) return invalid_args(msg); telephony_update_indicator(dummy_indicators, "battchg", level); DBG("telephony-dummy: battery level set to %u", level); return dbus_message_new_method_return(msg); }
static DBusMessage *signal_strength(DBusConnection *conn, DBusMessage *msg, void *data) { dbus_uint32_t strength; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &strength, DBUS_TYPE_INVALID)) return invalid_args(msg); if (strength > 5) return invalid_args(msg); telephony_update_indicator(dummy_indicators, "signal", strength); DBG("telephony-dummy: signal strength set to %u", strength); return dbus_message_new_method_return(msg); }
static DBusMessage *transfer_cancel(DBusConnection *connection, DBusMessage *msg, void *user_data) { struct obex_session *os = user_data; const char *sender; if (!os) return invalid_args(msg); sender = dbus_message_get_sender(msg); if (strcmp(agent->bus_name, sender) != 0) return not_authorized(msg); os->aborted = TRUE; return dbus_message_new_method_return(msg); }
static DBusMessage *set_subscriber_number(DBusConnection *conn, DBusMessage *msg, void *data) { const char *number; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &number, DBUS_TYPE_INVALID)) return invalid_args(msg); g_free(subscriber_number); subscriber_number = g_strdup(number); DBG("telephony-dummy: subscriber number set to %s", number); return dbus_message_new_method_return(msg); }
static DBusMessage *interface_version(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessage *reply; dbus_uint32_t version = 0; if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING)) return invalid_args(msg); reply = dbus_message_new_method_return(msg); if (!reply) return NULL; dbus_message_append_args(reply, DBUS_TYPE_UINT32, &version, DBUS_TYPE_INVALID); return reply; }
static DBusMessage *roaming_status(DBusConnection *conn, DBusMessage *msg, void *data) { dbus_bool_t roaming; int val; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &roaming, DBUS_TYPE_INVALID)) return invalid_args(msg); val = roaming ? EV_ROAM_ACTIVE : EV_ROAM_INACTIVE; telephony_update_indicator(dummy_indicators, "roam", val); DBG("telephony-dummy: roaming status set to %d", val); return dbus_message_new_method_return(msg); }
static DBusMessage *registration_status(DBusConnection *conn, DBusMessage *msg, void *data) { dbus_bool_t registration; int val; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, ®istration, DBUS_TYPE_INVALID)) return invalid_args(msg); val = registration ? EV_SERVICE_PRESENT : EV_SERVICE_NONE; telephony_update_indicator(dummy_indicators, "service", val); DBG("telephony-dummy: registration status set to %d", val); return dbus_message_new_method_return(msg); }
static DBusMessage *max_msg_size(DBusConnection *conn, DBusMessage *msg, void *data) { dbus_uint32_t size; if (sim_card_conn_status == SIM_CONNECTED) return g_dbus_create_error(msg, "org.bluez.Error.Failed", "Can't change msg size when connected."); if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &size, DBUS_TYPE_INVALID)) return invalid_args(msg); max_msg_size_supported = size; DBG("MaxMessageSize set to %d", max_msg_size_supported); return dbus_message_new_method_return(msg); }
static DBusMessage *card_status(DBusConnection *conn, DBusMessage *msg, void *data) { dbus_uint32_t status; DBG("status %d", sim_card_conn_status); if (sim_card_conn_status != SIM_CONNECTED) return g_dbus_create_error(msg, "org.bluez.Error.Failed", "Can't change msg size when not connected."); if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &status, DBUS_TYPE_INVALID)) return invalid_args(msg); switch (status) { case 0: /* card removed */ sim_card_conn_status = SIM_MISSING; sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_REMOVED); break; case 1: /* card inserted */ if (sim_card_conn_status == SIM_MISSING) { sim_card_conn_status = SIM_CONNECTED; sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_INSERTED); } break; case 2: /* card not longer available*/ sim_card_conn_status = SIM_POWERED_OFF; sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_NOT_ACCESSIBLE); break; default: return g_dbus_create_error(msg, "org.bluez.Error.Failed", "Unknown card status. Use 0, 1 or 2."); } DBG("Card status changed to %d", status); return dbus_message_new_method_return(msg); }
static DBusMessage *old_find_adapter(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessage *reply; char path[MAX_PATH_LENGTH], *path_ptr = path; struct hci_dev_info di; const char *pattern; int dev_id; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, DBUS_TYPE_INVALID)) return invalid_args(msg); /* hci_devid() would make sense to use here, except it is restricted to devices which are up */ if (!strncmp(pattern, "hci", 3) && strlen(pattern) >= 4) dev_id = atoi(pattern + 3); else dev_id = find_by_address(pattern); if (dev_id < 0) return no_such_adapter(msg); if (hci_devinfo(dev_id, &di) < 0) return no_such_adapter(msg); if (hci_test_bit(HCI_RAW, &di.flags)) return no_such_adapter(msg); reply = dbus_message_new_method_return(msg); if (!reply) return NULL; snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, dev_id); dbus_message_append_args(reply, DBUS_TYPE_STRING, &path_ptr, DBUS_TYPE_INVALID); return reply; }
static DBusMessage *ongoing_call(DBusConnection *conn, DBusMessage *msg, void *data) { dbus_bool_t ongoing; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &ongoing, DBUS_TYPE_INVALID)) return invalid_args(msg); if (ongoing_call_status && !ongoing) { /* An ongoing call has finished. Continue connection.*/ sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_RESET); ongoing_call_status = FALSE; } else if (!ongoing_call_status && ongoing) { /* An ongoing call has started.*/ ongoing_call_status = TRUE; } DBG("OngoingCall status set to %d", ongoing_call_status); return dbus_message_new_method_return(msg); }
static DBusMessage *old_default_adapter(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessage *reply; char path[MAX_PATH_LENGTH], *path_ptr = path; if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING)) return invalid_args(msg); if (default_adapter_id < 0) return no_such_adapter(msg); reply = dbus_message_new_method_return(msg); if (!reply) return NULL; snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, default_adapter_id); dbus_message_append_args(reply, DBUS_TYPE_STRING, &path_ptr, DBUS_TYPE_INVALID); return reply; }
static DBusMessage *list_services(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessage *reply; DBusMessageIter iter; DBusMessageIter array_iter; if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING)) return invalid_args(msg); reply = dbus_message_new_method_return(msg); if (!reply) return NULL; dbus_message_iter_init_append(reply, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &array_iter); append_available_services(&array_iter); dbus_message_iter_close_container(&iter, &array_iter); return reply; }
static DBusMessage *incoming_call(DBusConnection *conn, DBusMessage *msg, void *data) { const char *number; if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &number, DBUS_TYPE_INVALID)) return invalid_args(msg); DBG("telephony-dummy: incoming call to %s", number); g_free(active_call_number); active_call_number = g_strdup(number); telephony_update_indicator(dummy_indicators, "callsetup", EV_CALLSETUP_INCOMING); active_call_status = CALL_STATUS_INCOMING; active_call_dir = CALL_DIR_INCOMING; telephony_incoming_call_ind(number, NUMBER_TYPE_TELEPHONY); return dbus_message_new_method_return(msg); }
static DBusMessage *old_list_adapters(DBusConnection *conn, DBusMessage *msg, void *data) { DBusMessageIter iter; DBusMessageIter array_iter; DBusMessage *reply; struct hci_dev_list_req *dl; struct hci_dev_req *dr; int i, sk; if (!dbus_message_has_signature(msg, DBUS_TYPE_INVALID_AS_STRING)) return invalid_args(msg); sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (sk < 0) return failed_strerror(msg, errno); dl = g_malloc0(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl)); dl->dev_num = HCI_MAX_DEV; dr = dl->dev_req; if (ioctl(sk, HCIGETDEVLIST, dl) < 0) { int err = errno; close(sk); g_free(dl); return failed_strerror(msg, err); } dr = dl->dev_req; reply = dbus_message_new_method_return(msg); if (!reply) { close(sk); g_free(dl); return NULL; } dbus_message_iter_init_append(reply, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &array_iter); for (i = 0; i < dl->dev_num; i++, dr++) { char path[MAX_PATH_LENGTH], *path_ptr = path; struct hci_dev_info di; if (hci_devinfo(dr->dev_id, &di) < 0) continue; if (hci_test_bit(HCI_RAW, &di.flags)) continue; snprintf(path, sizeof(path), "%s/%s", BASE_PATH, di.name); dbus_message_iter_append_basic(&array_iter, DBUS_TYPE_STRING, &path_ptr); } dbus_message_iter_close_container(&iter, &array_iter); g_free(dl); close(sk); return reply; }
// 1. Extract arguments // 2. Initialize modules // 3. Launch candy-factory threads // 4. Launch kid threads // 5. Wait for requested time // 6. Stop candy-factory threads // 7. Wait until no more candy // 8. Stop kid threads // 9. Print statistics // 10. Cleanup any allocated memory int main(int argc, char* argv[]) { //1. Extract Arguments int factories = 0, kids = 0, seconds = 0; int* array[3] = {&factories, &kids, &seconds}; if(invalid_args(argc, argv)) { printf(INVALID_ARG_ERR); exit(1); } for(int i=1; i<=ARG_COUNT; i++){ sscanf(argv[i], "%d", array[i-1]); } //2. Initialize Modules srand(time(NULL)); bbuff_init(); stats_init(factories); //3. Launch candy-factory threads pthread_t* factory_thread_IDs = malloc(factories *(sizeof(pthread_t))); launch_threads(factories, factory_thread_IDs, (void*)factory_thread); //4. Launch kid threads pthread_t* kid_thread_IDs = malloc(kids *(sizeof(pthread_t))); launch_threads(kids, kid_thread_IDs, (void*)kid_thread); //5. Wait for requested time for(int i=0; i<seconds; i++) { sleep(1); printf("Time: %ds\n", i+1); } //6. Stop candy-factory threads stop_thread = true; for(int i=0; i<factories; i++) { pthread_join(factory_thread_IDs[i], NULL); } //7. Wait until no more candy while(!bbuff_is_empty()) { sleep(1); } //8. Stop kid threads for(int i=0; i<kids; i++) { pthread_cancel(kid_thread_IDs[i]); pthread_join(kid_thread_IDs[i], NULL); } //9. Print statistics stats_display(); //10. Cleanup any allocated memory stats_cleanup(); free(factory_thread_IDs); free(kid_thread_IDs); printf("Exiting program!\n"); return 0; }