/** Thread that handles incoming messages from mio * @param context * @param mio_sock */ static void* _mio_handler_write(void* vcontext) { multiplexer_context_t *context = (multiplexer_context_t*) vcontext; char* message = NULL; size_t message_len = 0; mio_response_t *response; while(1) { response = mio_response_new(); //printf("waiting for xmpp message\n"); mio_pubsub_data_receive(context -> mio_info -> mio, response); if (response -> stanza == NULL) { mio_response_free(response); printf("IPC ERROR: data receive stanza null\n"); continue; } //mio_stanza_to_text(response -> stanza, &message, &message_len); xmpp_stanza_to_text(response -> stanza -> xmpp_stanza, &message, &message_len); // receive message printf("Distributing\n%s\n",message); _distribute_message(context,message,0); mio_response_free(response); if (message_len != 0) free(message); } return NULL; }
// Handler to catch SIGINT (Ctrl+C) void int_handler(int s) { mio_disconnect(conn); mio_conn_free(conn); if (response != NULL ) mio_response_free(response); exit(1); }
/** Thread that handles outgoing messages to mio and incoming messages from * @param context * @param mio_sock */ static void* _mio_handler_read(void* vcontext) { multiplexer_context_t * context = vcontext; int fd = context -> mio_info -> miofd; char *stanza_response,*event_response ; mio_response_t *response; mio_stanza_t *stanza = NULL; mio_info_t *mio_info = context -> mio_info; while (mio_info -> mio -> xmpp_conn -> state != XMPP_STATE_CONNECTED) { usleep(1000); } mio_parser_t *parser = mio_parser_new(mio_info -> mio); char* publish_request; while(1) { /* read in buffer */ publish_request = _buffered_read(fd); if (publish_request == NULL) { sleep(1); continue; } printf("got a publish request\n"); stanza_response = malloc(strlen(publish_request)); event_response = malloc(500); sscanf(publish_request,"%s,%s",event_response,publish_request); stanza = mio_parse(parser, (char*) publish_request); /* Publish stanza to mio */ response = mio_response_new(); while (mio_info -> mio -> xmpp_conn -> state != XMPP_STATE_CONNECTED) usleep(1000); mio_item_publish_data(mio_info -> mio,stanza,event_response,response); mio_response_print(response); mio_response_free(response); mio_stanza_free(stanza); mio_response_free(response); free(stanza_response); free(publish_request); } return NULL; }
int register_user(mio_conn_t *conn, char *user, char *pass) { int err; mio_response_t *response = mio_response_new(); xmpp_stanza_t *iq = NULL, *query = NULL, *username = NULL, *username_tag = NULL, *password = NULL, *password_tag = NULL; mio_stanza_t *stanza = mio_stanza_new(conn); // Check if connection is active if (!conn->xmpp_conn->authenticated) { return MIO_ERROR_DISCONNECTED; } // Create a new user stanza iq = xmpp_stanza_new(conn->xmpp_conn->ctx); xmpp_stanza_set_name(iq, "iq"); xmpp_stanza_set_attribute(iq, "id", "reg2"); xmpp_stanza_set_type(iq, "set"); // Creqte query stanza query = xmpp_stanza_new(conn -> xmpp_conn -> ctx); xmpp_stanza_set_name(query,"query"); xmpp_stanza_set_ns(query,"jabber:iq:register"); // create username stanza username = xmpp_stanza_new(conn -> xmpp_conn -> ctx); username_tag = xmpp_stanza_new(conn -> xmpp_conn -> ctx); xmpp_stanza_set_name(username,"username"); xmpp_stanza_set_text(username_tag, user); // create password stanza password = xmpp_stanza_new(conn -> xmpp_conn -> ctx); password_tag = xmpp_stanza_new(conn -> xmpp_conn -> ctx); xmpp_stanza_set_name(password, "password"); xmpp_stanza_set_text(password_tag,pass); // create password stanza password = xmpp_stanza_new(conn -> xmpp_conn -> ctx); password_tag = xmpp_stanza_new(conn -> xmpp_conn -> ctx); xmpp_stanza_set_name(password, "password"); xmpp_stanza_set_text(password_tag,pass); // Build xmpp message xmpp_stanza_add_child(password, password_tag); xmpp_stanza_add_child(username, username_tag); xmpp_stanza_add_child(query, username); xmpp_stanza_add_child(query, password); xmpp_stanza_add_child(iq, query); stanza -> xmpp_stanza = iq; // Send out the stanza err = _mio_send_nonblocking(conn, stanza); // Release the stanzas mio_stanza_free(stanza); mio_response_free(response); return 0; }
static bacnet_context_t* parse_bacnet_context_node(adapter_t *adapter) { mio_response_t *bacnet_ref_response; mio_response_t *bacnet_meta_response; mio_reference_t *bacnet_ref; mio_reference_t *ref_tmp; int err, count; int bacnet_id; char *parser_object_type, *bacnet_name; bacnet_device_t *devices; bacnet_device_t *device; mio_meta_t *meta; mio_transducer_meta_t *transducer; mio_property_meta_t *property; char* node_id; bacnet_context_t *b_context = malloc(sizeof(bacnet_context_t)); memset(b_context, 0x0, sizeof(bacnet_context_t)); // get children bacnet_ref_response = mio_response_new(); err = mio_references_query(adapter -> connection, adapter -> config_dir, bacnet_ref_response); if (err != MIO_OK) { printf("Could not retrieve any children.\n"); return NULL; } // iterate through bacnet_children mio_packet_t *packet = (mio_packet_t*) bacnet_ref_response -> response; bacnet_ref = (mio_reference_t*) packet -> payload; for (ref_tmp = bacnet_ref; ref_tmp != NULL; ref_tmp = ref_tmp -> next) { if (ref_tmp -> type != MIO_REFERENCE_CHILD) { continue; } node_id = ref_tmp -> node; device = new_bacnet_device(); device -> node_id = parser_node_id; bacnet_meta_response = mio_response_new(); err = mio_meta_query(adapter -> connection, node_id, bacnet_meta_response ); if (err != MIO_OK) { continue; } packet = (mio_packet_t*) bacnet_meta_response -> response; meta = (mio_meta_t*) packet -> payload; // iterate over meta properties for (property = meta -> properties; property != NULL; property = property -> next) { if (strcmp(property -> name, "BACnet Type") == 0) { device -> type = string_copy(property -> value); } else if (strcmp(property -> name, "BACnet Instance") == 0) { device -> instance = atoi( property-> value); } /*else if (strcmp(property -> name, "BACnet IP Address") == 0) { }*/ } // iterate over transducers count = 0; for (transducer = meta -> transducers; transducer != NULL; transducer = transducer -> next) count++; device -> obj_ids = (int*) malloc(count * sizeof(int)); device -> obj_types = (int*) malloc(count * sizeof(int)); device -> obj_names = (char**) malloc(count * sizeof(char*)); for (transducer = meta -> transducers; transducer != NULL; transducer = transducer -> next) { // iterate over transducer properties // count = 0; for (property = transducer -> properties; property != NULL; property = property -> next) { if (strcmp(property -> name, "BACnet Type") == 0) { if (strcmp(property -> value,"AV") == 0) { device -> obj_types[count] = OBJECT_ANALOG_VALUE; } else if (strcmp(property -> value,"BV") == 0) { device -> obj_types[count] = OBJECT_BINARY_VALUE; } } else if (strcmp(property -> name, "BACnet Name") == 0) { device -> obj_names[count] = string_copy(property -> value); } else if (strcmp(property -> name, "BACnet ID") == 0) { device -> obj_ids[count] = atoi(property -> value); } count ++; } HASH_ADD(nodemap, b_context -> instance_devices, instance, sizeof(int32_t),device); HASH_ADD(instancemap, b_context -> node_devices, instance,strlen(device -> node_id),device); } mio_response_free(bacnet_meta_response); } return b_context; }
int publish_data(adapter_t *adapter) { static uint8_t rx_buf[MAX_MPDU] = {0}; bacnet_context_t *context = (bacnet_context_t*) (adapter -> context); bacnet_device_t *device; time_t current_seconds, elapsed_seconds = 0; int pdu_len; char *time_str, *node_id; time_t last_seconds,timeout_seconds; unsigned timeout = 100; BACNET_ADDRESS src = { 0 }; unsigned max_apdu = 0; mio_stanza_t *item; mio_response_t *publish_response; for (device = context -> node_devices; device; device = device -> nodemap.next) { time_str = mio_timestamp_create(); item = mio_pubsub_item_data_new(adapter -> connection); node_id = device -> node_id; last_seconds = time(NULL); timeout_seconds = (apdu_timeout() / 1000) * apdu_retries(); //if (!found) found = address_bind_request(device -> instance, &max_apdu, &target_address); if (!found) { Send_WhoIs(device -> instance, device -> instance); } while (!found) { current_seconds = time(NULL); if (current_seconds != last_seconds) tsm_timer_milliseconds((uint16_t) ((current_seconds - last_seconds) * 1000)); if (!found) { found = address_bind_request(device -> instance, &max_apdu,&target_address); } if (!found) { elapsed_seconds += (current_seconds - last_seconds); if (elapsed_seconds > timeout_seconds) { printf("\rError: APDU Timeout!\r\n"); return 1; } } pdu_len = datalink_receive(&src, &rx_buf[0], MAX_MPDU,timeout); if (pdu_len) { npdu_handler(&src, &rx_buf[0], pdu_len); } last_seconds = current_seconds; } int i; printf("n_objects %d\n", device -> n_objects); for ( i = 0; i < device -> n_objects; i++) { request_invoke_id = 0; while(TRUE) { printf("true\n"); if (found) { if (request_invoke_id == 0) { request_invoke_id = Send_Read_Property_Request( device->instance, device -> obj_types[i], device -> obj_ids[i], 85, -1); } else if (tsm_invoke_id_free(request_invoke_id)) break; else if (tsm_invoke_id_failed(request_invoke_id)) { fprintf(stderr,"\rError: TSM Timeout!\r\n"); tsm_free_invoke_id(request_invoke_id); return 1; } } pdu_len = datalink_receive(&src, &rx_buf[0], MAX_MPDU,timeout); if (pdu_len) { npdu_handler(&src, &rx_buf[0], pdu_len); } last_seconds = current_seconds; } if (error_detected) { error_detected = 0; return 1; } else { if (strcmp(value,"active") == 0) mio_item_transducer_value_add(item, NULL, device -> obj_names[i] , "1", value, time_str); else if (strcmp(value,"inactive") == 0) mio_item_transducer_value_add(item, NULL, device -> obj_names[i] , "0",value, time_str); else mio_item_transducer_value_add(item, NULL, device -> obj_names[i] , value, value, time_str); } } publish_response = mio_response_new(); while (adapter -> connection -> xmpp_conn -> state != XMPP_STATE_CONNECTED) usleep(1000); mio_item_publish_data(adapter -> connection,item,node_id,publish_response); free(time_str); mio_response_print(publish_response); mio_response_free(publish_response); mio_stanza_free(item); } return 0; }
void* bacnet_actuate(void* vadapter) { adapter_t *adapter = (adapter_t*) vadapter; bacnet_context_t *context = (bacnet_context_t*) (adapter -> context); mio_conn_t* pubsub_conn = adapter -> connection; mio_packet_t* packet; mio_data_t* data; mio_response_t* response; mio_transducer_value_t* tran; int32_t err; bacnet_device_t *device; while (TRUE) { if (pubsub_conn -> xmpp_conn -> state == XMPP_STATE_CONNECTED) { response = mio_response_new(); err = mio_pubsub_data_receive(pubsub_conn, response); if (err != MIO_OK) { printf("mio_pubsub_data_receive failed with error: %d\n", err); continue; } pthread_mutex_lock(mio_lock); packet = (mio_packet_t*) response->response; data = (mio_data_t*) packet->payload; for (tran = data->transducers; tran != NULL; tran = tran->next) { if (tran -> type != MIO_TRANSDUCER_SET_VALUE) continue; else { for (device = context -> node_devices; device; device = device -> nodemap.next) { if (strcmp(device -> node_id,data->event) !=0) continue; int i; for (i = 0; i < device -> n_objects; i++) { if (strcmp(device -> obj_names[i],tran -> name) == 0) { break; } } if (i == device -> n_objects) { continue; } err = write_bacnet_obj(device, i, tran -> typed_value); if (err) printf("error with writing bacnet object\n"); } } } pthread_mutex_unlock(mio_lock); mio_response_free(response); } else usleep(1000); } }
int main(int argc, char **argv) { //parse command line arguments benchmark_t *setup = parse_args(argc,argv); // setup user connection mio_conn_t *conn = mio_conn_new(); mio_connect(setup -> user, setup -> pass, MIO_LEVEL_DEBUG, NULL, NULL, conn); // - register new publishers // - connect new publishers // - register new publishers event nodes int user_index, error, node_index; char tmp_username[UUID_LENGTH]; char tmp_password[UUID_LENGTH]; char *tmp_node_id,*tmp_jid; mio_response_t *response = NULL; uuid_t tmp_uuid; srand(time(NULL)); thread_args_t *thread_args; publishers = malloc(setup -> n_publishers * sizeof(mio_conn_t*)); memset(publishers, 0x0, setup -> n_publishers * sizeof(mio_conn_t*)); publish_nodes = (char***) malloc(setup -> n_publishers * sizeof(char**)); publish_count = (int**) malloc(setup -> n_publishers *sizeof(int*)); for (user_index = 0; user_index < setup -> n_publishers; user_index++) { uuid_generate(tmp_uuid); uuid_unparse(tmp_uuid,tmp_username); uuid_generate(tmp_uuid); uuid_unparse(tmp_uuid,tmp_password); error = register_user(conn, tmp_username,tmp_password); publishers[user_index] = mio_conn_new(); if (error) { printf("error registering user %s \n", tmp_username); } else { tmp_jid = malloc(100); sprintf(tmp_jid,"%s@%s", tmp_username, setup -> server); mio_connect(tmp_jid, tmp_password, MIO_LEVEL_ERROR, NULL,NULL,publishers[user_index]); } publish_nodes[user_index] = malloc(setup -> publish_factor * sizeof(char*)); for (node_index = 0; node_index < setup -> publish_factor; node_index++) { tmp_node_id = malloc(UUID_LENGTH * sizeof(char)); uuid_generate(tmp_uuid); uuid_unparse(tmp_uuid,tmp_node_id); publish_nodes[user_index][node_index] = tmp_node_id; response = mio_response_new(); mio_node_create(publishers[user_index], tmp_node_id, "", NULL, response); mio_response_free(response); tmp_node_id = NULL; } publish_count[user_index] = (int*) malloc(sizeof(int)*setup -> publish_factor); memset(publish_count[user_index],0x0,sizeof(int)*setup -> publish_factor); memset(tmp_username,0x0,UUID_LENGTH); memset(tmp_password,0x0,UUID_LENGTH); } // register new subscribers // connect new subscribers // randomly assign the nodes to subscribe to // initialize count matrix subscribers = malloc(setup -> n_subscribers * sizeof(mio_conn_t*)); memset(subscribers, 0x0, setup -> n_subscribers * sizeof(mio_conn_t*)); subscribe_nodes = (char***) malloc(setup -> n_subscribers * sizeof(char**)); subscribe_count = (int**) malloc(setup -> n_subscribers *sizeof(int*)); printf("%d\n", setup -> n_subscribers); for (user_index = 0; user_index < setup -> n_subscribers; user_index++) { uuid_generate(tmp_uuid); uuid_unparse(tmp_uuid,tmp_username); uuid_generate(tmp_uuid); uuid_unparse(tmp_uuid,tmp_password); subscribers[user_index] = mio_conn_new(); error = register_user(conn, tmp_username,tmp_password); if (error) { printf("error registering user %s \n", tmp_username); } else { tmp_jid = malloc(100); sprintf(tmp_jid,"%s@%s", tmp_username,setup -> server); mio_connect(tmp_jid, tmp_password, MIO_LEVEL_ERROR, NULL,NULL,subscribers[user_index]); } subscribe_nodes[user_index] = malloc(setup -> subscribe_factor * sizeof(char*)); int pub_index = (user_index * setup -> subscribe_factor)/(setup -> publish_factor) % setup -> n_publishers; int event_index = (user_index * setup -> subscribe_factor) % (setup -> publish_factor); for (node_index = 0; node_index < setup -> subscribe_factor; node_index++) { printf("%d node, %d pub, %d event\n", node_index, pub_index, event_index); tmp_node_id = publish_nodes[pub_index][ event_index]; subscribe_nodes[user_index][node_index] = tmp_node_id; response = mio_response_new(); error = mio_subscribe(subscribers[user_index], tmp_node_id, response); mio_response_free(response); event_index++; pub_index += event_index / setup -> publish_factor; pub_index = pub_index % setup -> n_publishers; event_index = event_index % setup -> publish_factor; } subscribe_count[user_index] = (int*) malloc(sizeof(int)*setup -> subscribe_factor); memset(subscribe_count[user_index],0x0,sizeof(int)*setup -> subscribe_factor); memset(tmp_username,0x0,UUID_LENGTH); memset(tmp_password,0x0,UUID_LENGTH); } publish_threads = (pthread_t*) malloc(setup -> n_publishers*sizeof(pthread_t)); subscribe_threads = (pthread_t*) malloc(setup -> n_publishers*sizeof(pthread_t)); // spawn process for each subscriber // spawn process for each publisher for (user_index = 0; user_index < setup -> n_subscribers; user_index++) { thread_args = (thread_args_t*) malloc(sizeof(thread_args_t)); thread_args -> user_index = user_index; thread_args -> setup = setup; pthread_create(&subscribe_threads[user_index], NULL, (void*) &subscriber_thread, thread_args); } for (user_index = 0; user_index < setup -> n_publishers; user_index++) { thread_args = (thread_args_t*) malloc(sizeof(thread_args_t)); thread_args -> user_index = user_index; thread_args -> setup = setup; pthread_create(&publish_threads[user_index], NULL, (void*) &publisher_thread, thread_args); } // have subscribers and publishers increment // kill all threads after proveided time long elapsed = 0; long last_time = time(NULL), time_tmp; while(elapsed < setup -> time) { sleep(setup -> time /10); time_tmp = time(NULL); elapsed += time_tmp - last_time; last_time = time_tmp; } for (user_index = 0; user_index < setup -> n_subscribers; user_index++) { pthread_cancel(subscribe_threads[user_index]); } for (user_index = 0; user_index < setup -> n_publishers; user_index++) { pthread_cancel(publish_threads[user_index]); } print_results(setup); return 0; }
int subscriber_thread(thread_args_t *thread_args) { int sub_index = thread_args -> user_index; benchmark_t *setup = thread_args -> setup; char *event_node; mio_conn_t *conn = subscribers[sub_index]; if (conn == NULL) printf("sub conn is null\n"); mio_data_t * mio_data = NULL; mio_response_t *response = NULL; mio_packet_t *mio_packet = NULL; int node_index; while (1) { response = mio_response_new(); mio_pubsub_data_receive(conn, response); //This is a handy toowwwwwwl for printing response information // For the purpose of illustration, we will manually print the elements // mio_response_print(response); //Parse the response packet type switch (response->response_type) { //For commands that require an acknowledgment, it can be checked with MIO_RESPONSE_OK case MIO_RESPONSE_OK: break; //For errors, the code can be printed as described below case MIO_RESPONSE_ERROR: break; //If the response contains more complex data, it is encapsulated in a MIO_RESPONSE_PACKET case MIO_RESPONSE_PACKET: mio_packet = (mio_packet_t *) response->response; //Since there are multiple types of responses, you typically first switch on the type if (mio_packet->type == MIO_PACKET_DATA) { //MIO_PACKET_DATA contains a list of transducer values that contain data mio_data = (mio_data_t *) mio_packet-> payload; event_node = mio_data->event; //Traverse the linked list of sensor values for (node_index = 0; node_index < setup -> subscribe_factor; node_index++ ) { if (strcmp(event_node, subscribe_nodes[sub_index][node_index]) == 0) { subscribe_count[sub_index][node_index]++; break; } } } else printf("Unknown MIO response packet\n"); break; default: printf("unknown response type\n"); } mio_response_free(response); } return 0; }
int main(int argc, char **argv) { char *username = NULL; char *password = NULL; char *xmpp_server = NULL; char pubsub_server[80]; int xmpp_server_port = 5223; int verbose = 0; int current_arg_num = 1; char *current_arg_name = NULL; char *current_arg_val = NULL; struct sigaction sig_int_handler; // Add SIGINT handler sig_int_handler.sa_handler = int_handler; sigemptyset(&sig_int_handler.sa_mask); sig_int_handler.sa_flags = 0; sigaction(SIGINT, &sig_int_handler, NULL ); if (argc == 1 || !strcmp(argv[1], "-help")) { print_usage(argv[0]); return -1; } while (current_arg_num < argc) { current_arg_name = argv[current_arg_num++]; if (strcmp(current_arg_name, "-help") == 0) { print_usage(argv[0]); return -1; } if (strcmp(current_arg_name, "-verbose") == 0) { verbose = 1; continue; } if (current_arg_num == argc) { print_usage(argv[0]); return -1; } current_arg_val = argv[current_arg_num++]; if (strcmp(current_arg_name, "-u") == 0) { username = current_arg_val; xmpp_server = _mio_get_server(username); if (xmpp_server == NULL ) { fprintf(stderr, "Invalid JID, use format user@domain\n"); return MIO_ERROR_INVALID_JID; } strcpy(pubsub_server, "pubsub."); strcat(pubsub_server, xmpp_server); } else if (strcmp(current_arg_name, "-p") == 0) { password = current_arg_val; } else { fprintf(stderr, "Unknown argument: %s\n", current_arg_name); print_usage(argv[0]); return -1; } } if (username == NULL ) { fprintf(stderr, "Username missing\n"); print_usage(argv[0]); return -1; } else if (password == NULL ) { fprintf(stderr, "Password missing\n"); print_usage(argv[0]); return -1; } if (verbose) { fprintf(stdout, "XMPP Server: %s\n", xmpp_server); fprintf(stdout, "XMPP Server Port: %d\n", xmpp_server_port); fprintf(stdout, "XMPP PubSub Server: %s\n", pubsub_server); fprintf(stdout, "Username: %s\n", username); fprintf(stdout, "Verbose: YES\n"); fprintf(stdout, "\n"); } if (verbose == 0){ conn = mio_conn_new(MIO_LEVEL_ERROR); mio_connect(username, password, NULL, NULL, conn); } else{ conn = mio_conn_new(MIO_LEVEL_DEBUG); mio_connect(username, password, NULL, NULL, conn); } while (1) { response = mio_response_new(); mio_pubsub_data_receive(conn, response); //This is a handy tool for printing response information // For the purpose of illustration, we will manually print the elements // mio_response_print(response); //Parse the response packet type switch (response->response_type) { //For commands that require an acknowledgment, it can be checked with MIO_RESPONSE_OK case MIO_RESPONSE_OK: printf("Request Successful\n"); break; //For errors, the code can be printed as described below case MIO_RESPONSE_ERROR: printf("Response error: "); mio_err = response->response; fprintf(stderr, "MIO Error:\n"); fprintf(stderr, "\tError code: %d\n\tError description: %s\n", mio_err->err_num, mio_err->description); break; //If the response contains more complex data, it is encapsulated in a MIO_RESPONSE_PACKET case MIO_RESPONSE_PACKET: mio_packet = (mio_packet_t *) response->response; //Since there are multiple types of responses, you typically first switch on the type if (mio_packet->type == MIO_PACKET_DATA) { //MIO_PACKET_DATA contains a list of transducer values that contain data mio_data = (mio_data_t *) mio_packet->payload; printf("MIO Data Packet:\n\tEvent Node:%s\n", mio_data->event); mio_tran = mio_data->transducers; //Traverse the linked list of sensor values while (mio_tran != NULL ) { if (mio_tran->type == MIO_TRANSDUCER_VALUE) printf("\t\tTrasducerValue:\n"); else printf("\t\tTrasducerSetValue:\n"); printf( "\t\t\tName: %s\n\t\t\tID: %d\n\t\t\tRaw Value: %s\n\t\t\tTyped Value: %s\n\t\t\tTimestamp: %s\n", mio_tran->name, mio_tran->id, mio_tran->raw_value, mio_tran->typed_value, mio_tran->timestamp); mio_tran = mio_tran->next; } } else printf("Unknown MIO response packet\n"); break; default: printf("unknown response type\n"); } mio_response_free(response); } return 0; }