Esempio n. 1
0
void ipcon_dispatch(IPConnection *ipcon) {
	unsigned char buffer[RECV_BUFFER_SIZE] = { 0 };
	int length = read(ipcon->fd, buffer, RECV_BUFFER_SIZE);
	if(length < 0) {
		unsigned char* buf = buffer;
		int handled = 0;
		do {
			uint8_t function_id = ipcon_get_function_id_from_data(buf);
			uint16_t part_length = ipcon_get_length_from_data(buf);
			handled += part_length;
			if (function_id == FUNCTION_ENUMERATE_CALLBACK) {
				EnumerateReturn *er = (EnumerateReturn *)buf;
				char str_uid[MAX_BASE58_STR_SIZE];
				ipcon_base58encode(er->device_uid, str_uid);				
				if (ipcon->enumerate_callback != NULL) {
					ipcon->enumerate_callback(str_uid,
								  er->device_name,
								  er->device_stack_id,
								  er->is_new);
				}
			} else {
				uint8_t stack_id = ipcon_get_stack_id_from_data(buf);
				Device *device = ipcon->devices[stack_id];				
				device->device_callbacks[function_id](device, buf);				
			}
			buf += part_length;			
		} while(handled < length);
	}
}
Esempio n. 2
0
static THREAD_RETURN_TYPE ipcon_callback_loop(void *param) {
	IPConnection *ipcon = (IPConnection*)param;

	while(ipcon->thread_callback_flag) {
		if(!ipcon_semaphore_request(ipcon->callback_queue_semaphore)) {
			continue;
		}

		if(!ipcon->thread_callback_flag) {
			break;
		}

		if(ipcon->callback_queue_head == NULL) {
			continue;
		}

		ipcon_mutex_lock(&ipcon->callback_queue_mutex);

		CallbackQueueNode *node = ipcon->callback_queue_head;
		ipcon->callback_queue_head = node->next;
		node->next = NULL;

		if(ipcon->callback_queue_tail == node) {
			ipcon->callback_queue_head = NULL;
			ipcon->callback_queue_tail = NULL;
		}

		ipcon_mutex_unlock(&ipcon->callback_queue_mutex);

		uint8_t function_id = ipcon_get_function_id_from_data(node->buffer);
		if(function_id == FUNCTION_ENUMERATE_CALLBACK) {
			EnumerateReturn *er = (EnumerateReturn *)node->buffer;

			er->length = ipcon_leconvert_uint16_from(er->length);
			er->device_uid = ipcon_leconvert_uint64_from(er->device_uid);

			char str_uid[MAX_BASE58_STR_SIZE];
			ipcon_base58encode(er->device_uid, str_uid);

			if(ipcon->enumerate_callback != NULL) {
				ipcon->enumerate_callback(str_uid,
				                          er->device_name,
				                          er->device_stack_id,
				                          er->is_new);
			}
		} else {
			uint8_t stack_id = ipcon_get_stack_id_from_data(node->buffer);
			Device *device = ipcon->devices[stack_id];

			device->callback_wrappers[function_id](device, node->buffer);
		}

		free(node);
	}

	THREAD_RETURN;
}
Esempio n. 3
0
void ipcon_handle_message(IPConnection *ipcon, const unsigned char *buffer) {
	uint8_t function_id = ipcon_get_function_id_from_data(buffer);
	if(function_id == FUNCTION_GET_STACK_ID) {
		ipcon_handle_add_device(ipcon, buffer);
		return;
	}

	if(function_id == FUNCTION_ENUMERATE_CALLBACK) {
		ipcon_handle_enumerate(ipcon, buffer);
		return;
	}

	uint8_t stack_id = ipcon_get_stack_id_from_data(buffer);
	uint16_t length = ipcon_get_length_from_data(buffer);
	if(ipcon->devices[stack_id] == NULL) {
		// Response from an unknown device, ignoring it
		return;
	}

	Device *device = ipcon->devices[stack_id];
	DeviceResponse *response = &device->response;

	if(response->function_id == function_id) {
		if(response->length != length) {
			fprintf(stderr,
			        "Received malformed message from %d, ignoring it\n",
			        stack_id);
			return;
		}

		memcpy(response->buffer, buffer, length);
		response->length = length;

#ifdef _WIN32
		ReleaseSemaphore(device->response_semaphore, 1, NULL);
#else
		pthread_mutex_lock(&device->response_mutex);
		device->response_flag = true;
		pthread_cond_signal(&device->response_cond);
		pthread_mutex_unlock(&device->response_mutex);
#endif
		return;
	}

	if(device->registered_callbacks[function_id] != NULL) {
		ipcon_callback_queue_enqueue(ipcon, buffer);
		return;
	}

	// Message seems to be OK, but can't be handled, most likely
	// a callback without registered function
}
Esempio n. 4
0
void ipcon_callback_loop(void *param) {
#else
void *ipcon_callback_loop(void *param) {
#endif
	IPConnection *ipcon = (IPConnection*)param;

	while(ipcon->recv_loop_flag) {
#ifdef _WIN32
		if (WaitForSingleObject(ipcon->callback_queue_semaphore, INFINITE) != 0) {
			continue;
		}
#else
		if (sem_wait(ipcon->callback_queue_semaphore) != 0) {
			continue;
		}
#endif

		if (!ipcon->recv_loop_flag) {
			break;
		}

		if (ipcon->callback_queue_head == NULL) {
			continue;
		}

#ifdef _WIN32
		EnterCriticalSection(&ipcon->callback_queue_mutex);
#else
		pthread_mutex_lock(&ipcon->callback_queue_mutex);
#endif

		CallbackQueueNode *node = ipcon->callback_queue_head;
		ipcon->callback_queue_head = node->next;
		node->next = NULL;

		if (ipcon->callback_queue_tail == node) {
			ipcon->callback_queue_head = NULL;
			ipcon->callback_queue_tail = NULL;
		}

#ifdef _WIN32
		LeaveCriticalSection(&ipcon->callback_queue_mutex);
#else
		pthread_mutex_unlock(&ipcon->callback_queue_mutex);
#endif

		uint8_t function_id = ipcon_get_function_id_from_data(node->buffer);
		if (function_id == FUNCTION_ENUMERATE_CALLBACK) {
			EnumerateReturn *er = (EnumerateReturn *)node->buffer;
			char str_uid[MAX_BASE58_STR_SIZE];
			ipcon_base58encode(er->device_uid, str_uid);

			if (ipcon->enumerate_callback != NULL) {
				ipcon->enumerate_callback(str_uid,
				                          er->device_name,
				                          er->device_stack_id,
				                          er->is_new);
			}
		} else {
			uint8_t stack_id = ipcon_get_stack_id_from_data(node->buffer);
			Device *device = ipcon->devices[stack_id];

			device->device_callbacks[function_id](device, node->buffer);
		}

		free(node);
	}
#ifndef _WIN32
	return NULL;
#endif
}