Exemple #1
0
int MQTTClient_create(MQTTClient* handle, const char* serverURI, const char* clientId,
		int persistence_type, void* persistence_context)
{
	int rc = 0;
	MQTTClients *m = NULL;

	FUNC_ENTRY;
	rc = Thread_lock_mutex(mqttclient_mutex);

	if (serverURI == NULL || clientId == NULL)
	{
		rc = MQTTCLIENT_NULL_PARAMETER;
		goto exit;
	}

	if (!UTF8_validateString(clientId))
	{
		rc = MQTTCLIENT_BAD_UTF8_STRING;
		goto exit;
	}

	if (!initialized)
	{
		#if defined(HEAP_H)
			Heap_initialize();
		#endif
		Log_initialize((Log_nameValue*)MQTTClient_getVersionInfo());
		bstate->clients = ListInitialize();
		Socket_outInitialize();
		Socket_setWriteCompleteCallback(MQTTClient_writeComplete);
		handles = ListInitialize();
#if defined(OPENSSL)
		SSLSocket_initialize();
#endif
		initialized = 1;
	}
	m = malloc(sizeof(MQTTClients));
	*handle = m;
	memset(m, '\0', sizeof(MQTTClients));
	if (strncmp(URI_TCP, serverURI, strlen(URI_TCP)) == 0)
		serverURI += strlen(URI_TCP);
#if defined(OPENSSL)
	else if (strncmp(URI_SSL, serverURI, strlen(URI_SSL)) == 0)
	{
		serverURI += strlen(URI_SSL);
		m->ssl = 1;
	}
#endif
	m->serverURI = MQTTStrdup(serverURI);
	ListAppend(handles, m, sizeof(MQTTClients));

	m->c = malloc(sizeof(Clients));
	memset(m->c, '\0', sizeof(Clients));
	m->c->context = m;
	m->c->outboundMsgs = ListInitialize();
	m->c->inboundMsgs = ListInitialize();
	m->c->messageQueue = ListInitialize();
	m->c->clientID = MQTTStrdup(clientId);
	m->connect_sem = Thread_create_sem();
	m->connack_sem = Thread_create_sem();
	m->suback_sem = Thread_create_sem();
	m->unsuback_sem = Thread_create_sem();

#if !defined(NO_PERSISTENCE)
	rc = MQTTPersistence_create(&(m->c->persistence), persistence_type, persistence_context);
	if (rc == 0)
	{
		rc = MQTTPersistence_initialize(m->c, m->serverURI);
		if (rc == 0)
			MQTTPersistence_restoreMessageQueue(m->c);
	}
#endif
	ListAppend(bstate->clients, m->c, sizeof(Clients) + 3*sizeof(List));

exit:
	Thread_unlock_mutex(mqttclient_mutex);
	FUNC_EXIT_RC(rc);
	return rc;
}
Exemple #2
0
int MQTTClient_subscribeMany(MQTTClient handle, int count, char* const* topic, int* qos)
{
	MQTTClients* m = handle;
	List* topics = ListInitialize();
	List* qoss = ListInitialize();
	int i = 0;
	int rc = MQTTCLIENT_FAILURE;
	int msgid = 0;

	FUNC_ENTRY;
	Thread_lock_mutex(mqttclient_mutex);

	if (m == NULL || m->c == NULL)
	{
		rc = MQTTCLIENT_FAILURE;
		goto exit;
	}
	if (m->c->connected == 0)
	{
		rc = MQTTCLIENT_DISCONNECTED;
		goto exit;
	}
	for (i = 0; i < count; i++)
	{
		if (!UTF8_validateString(topic[i]))
		{
			rc = MQTTCLIENT_BAD_UTF8_STRING;
			goto exit;
		}
		
		if(qos[i] < 0 || qos[i] > 2)
		{
			rc = MQTTCLIENT_BAD_QOS;
			goto exit;
		}
	}
	if ((msgid = MQTTProtocol_assignMsgId(m->c)) == 0)
	{
		rc = MQTTCLIENT_MAX_MESSAGES_INFLIGHT;
		goto exit;
	}

	for (i = 0; i < count; i++)
	{
		ListAppend(topics, topic[i], strlen(topic[i]));
		ListAppend(qoss, &qos[i], sizeof(int));
	}

	rc = MQTTProtocol_subscribe(m->c, topics, qoss, msgid);
	ListFreeNoContent(topics);
	ListFreeNoContent(qoss);

	if (rc == TCPSOCKET_COMPLETE)
	{
		MQTTPacket* pack = NULL;

		Thread_unlock_mutex(mqttclient_mutex);
		pack = MQTTClient_waitfor(handle, SUBACK, &rc, 10000L);
		Thread_lock_mutex(mqttclient_mutex);
		if (pack != NULL)
		{
			Suback* sub = (Suback*)pack;	
			ListElement* current = NULL;
			i = 0;
			while (ListNextElement(sub->qoss, &current))
			{
				int* reqqos = (int*)(current->content);
				qos[i++] = *reqqos;
			}	
			rc = MQTTProtocol_handleSubacks(pack, m->c->net.socket);
			m->pack = NULL;
		}
		else
			rc = SOCKET_ERROR;
	}

	if (rc == SOCKET_ERROR)
	{
		Thread_unlock_mutex(mqttclient_mutex);
		MQTTClient_disconnect_internal(handle, 0);
		Thread_lock_mutex(mqttclient_mutex);
	}
	else if (rc == TCPSOCKET_COMPLETE)
		rc = MQTTCLIENT_SUCCESS;

exit:
	Thread_unlock_mutex(mqttclient_mutex);
	FUNC_EXIT_RC(rc);
	return rc;
}
Exemple #3
0
int MQTTClient_unsubscribeMany(MQTTClient handle, int count, char* const* topic)
{
	MQTTClients* m = handle;
	List* topics = ListInitialize();
	int i = 0;
	int rc = SOCKET_ERROR;
	int msgid = 0;

	FUNC_ENTRY;
	Thread_lock_mutex(mqttclient_mutex);

	if (m == NULL || m->c == NULL)
	{
		rc = MQTTCLIENT_FAILURE;
		goto exit;
	}
	if (m->c->connected == 0)
	{
		rc = MQTTCLIENT_DISCONNECTED;
		goto exit;
	}
	for (i = 0; i < count; i++)
	{
		if (!UTF8_validateString(topic[i]))
		{
			rc = MQTTCLIENT_BAD_UTF8_STRING;
			goto exit;
		}
	}
	if ((msgid = MQTTProtocol_assignMsgId(m->c)) == 0)
	{
		rc = MQTTCLIENT_MAX_MESSAGES_INFLIGHT;
		goto exit;
	}

	for (i = 0; i < count; i++)
		ListAppend(topics, topic[i], strlen(topic[i]));
	rc = MQTTProtocol_unsubscribe(m->c, topics, msgid);
	ListFreeNoContent(topics);

	if (rc == TCPSOCKET_COMPLETE)
	{
		MQTTPacket* pack = NULL;

		Thread_unlock_mutex(mqttclient_mutex);
		pack = MQTTClient_waitfor(handle, UNSUBACK, &rc, 10000L);
		Thread_lock_mutex(mqttclient_mutex);
		if (pack != NULL)
		{
			rc = MQTTProtocol_handleUnsubacks(pack, m->c->net.socket);
			m->pack = NULL;
		}
		else
			rc = SOCKET_ERROR;
	}

	if (rc == SOCKET_ERROR)
	{
		Thread_unlock_mutex(mqttclient_mutex);
		MQTTClient_disconnect_internal(handle, 0);
		Thread_lock_mutex(mqttclient_mutex);
	}

exit:
	Thread_unlock_mutex(mqttclient_mutex);
	FUNC_EXIT_RC(rc);
	return rc;
}
Exemple #4
0
/**
 *  Create a new socket and TCP connect to an address/port
 *  @param addr the address string
 *  @param port the TCP port
 *  @param sock returns the new socket
 *  @return completion code
 */
int Socket_new(char* addr, int port, int* sock)
{
	int type = SOCK_STREAM;
	struct sockaddr_in address;
#if defined(AF_INET6)
	struct sockaddr_in6 address6;
#endif
	int rc = SOCKET_ERROR;
#if defined(WIN32) || defined(WIN64)
	short family;
#else
	sa_family_t family = AF_INET;
#endif
	struct addrinfo *result = NULL;
	struct addrinfo hints = {0, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP, 0, NULL, NULL, NULL};

	FUNC_ENTRY;
	*sock = -1;

	if (addr[0] == '[')
	  ++addr;

	if ((rc = getaddrinfo(addr, NULL, &hints, &result)) == 0)
	{
		struct addrinfo* res = result;

		/* prefer ip4 addresses */
		while (res)
		{
			if (res->ai_family == AF_INET)
			{
				result = res;
				break;
			}
			res = res->ai_next;
		}

		if (result == NULL)
			rc = -1;
		else
#if defined(AF_INET6)
		if (result->ai_family == AF_INET6)
		{
			address6.sin6_port = htons(port);
			address6.sin6_family = family = AF_INET6;
			address6.sin6_addr = ((struct sockaddr_in6*)(result->ai_addr))->sin6_addr;
		}
		else
#endif
		if (result->ai_family == AF_INET)
		{
			address.sin_port = htons(port);
			address.sin_family = family = AF_INET;
			address.sin_addr = ((struct sockaddr_in*)(result->ai_addr))->sin_addr;
		}
		else
			rc = -1;

    freeaddrinfo(result);
	}
  else
  	Log(TRACE_MIN, -1, "getaddrinfo failed for addr %s with rc %d", addr, rc);

	if (rc != 0)
		Log(LOG_ERROR, -1, "%s is not a valid IP address", addr);
	else
	{
		*sock =	socket(family, type, 0);
		if (*sock == INVALID_SOCKET)
			rc = Socket_error("socket", *sock);
		else
		{
#if defined(NOSIGPIPE)
			int opt = 1;

			if (setsockopt(*sock, SOL_SOCKET, SO_NOSIGPIPE, (void*)&opt, sizeof(opt)) != 0)
				Log(TRACE_MIN, -1, "Could not set SO_NOSIGPIPE for socket %d", *sock);
#endif

			Log(TRACE_MIN, -1, "New socket %d for %s, port %d",	*sock, addr, port);
			if (Socket_addSocket(*sock) == SOCKET_ERROR)
				rc = Socket_error("setnonblocking", *sock);
			else
			{
				/* this could complete immmediately, even though we are non-blocking */
				if (family == AF_INET)
					rc = connect(*sock, (struct sockaddr*)&address, sizeof(address));
	#if defined(AF_INET6)
				else
					rc = connect(*sock, (struct sockaddr*)&address6, sizeof(address6));
	#endif
				if (rc == SOCKET_ERROR)
					rc = Socket_error("connect", *sock);
				if (rc == EINPROGRESS || rc == EWOULDBLOCK)
				{
					int* pnewSd = (int*)malloc(sizeof(int));
					*pnewSd = *sock;
					ListAppend(s.connect_pending, pnewSd, sizeof(int));
					Log(TRACE_MIN, 15, "Connect pending");
				}
			}
		}
	}
	FUNC_EXIT_RC(rc);
	return rc;
}
SInt64 MqttServer::Run()
{
    EventFlags events = this->GetEvents();
	this->ForceSameThread();

	// Http session is short connection, need to kill session when occur TimeoutEvent.
	// So return -1.
	if(events&Task::kTimeoutEvent || events&Task::kKillEvent)
		return -1;

    ZQ_Error err = ZQ_NoErr;
    
    while (this->IsLiveSession())
    {
        // HTTP Session state machine. There are several well defined points in an HTTP request
        // where this session may have to return from its run function and wait for a new event.
        // Because of this, we need to track our current state and return to it.
		if(events&Task::kReadEvent)
		{
			if ((err = fInputStream.ReadRequest()) == ZQ_NoErr)
			{
				//+rt use the socket that reads the data, may be different now.
				fInputSocketP->RequestEvent(EV_RE);
				events -= Task::kReadEvent;
				continue; 
			}
				
			if ((err != ZQ_RequestArrived) && (err != E2BIG))
			{
				// Any other error implies that the client has gone away. At this point,
				// we can't have 2 sockets, so we don't need to do the "half closed" check
				// we do below
				Assert(err > 0); 
				Assert(!this->IsLiveSession());
				events -= Task::kReadEvent; 
				break; 
			}
				
			if (err == ZQ_RequestArrived)
			{
				char* pBuffer = fInputStream.GetRequestBuffer();
				int nLen = fInputStream.GetRequsetLength();
				ZQ_Error err = ZQ_NoErr;
				while(err == ZQ_NoErr && nLen > 0)
				{
					err = ProcessRecvMsg(pBuffer, nLen);
				}
				
				if(ZQ_NoErr == err)
				{
					err = fOutputStream.Flush();
					if (err == EAGAIN)
					{
						UInt32 datalen = 0;
						char* pData = fOutputStream.GetBufferCopy(&datalen);
						if(pData)
						{
							OSMutexLocker locker(&fMutexList); 
							ListAppend(&fMsgList, pData, datalen);
						}
						// If we get this error, we are currently flow-controlled and should
						// wait for the socket to become writeable again
						fSocket.RequestEvent(EV_RE | EV_WR);
					}
				}
				else
				{
					CleanupRequest();
				}
			};
		}
		else if(events&Task::kWriteEvent)
		{
			OSMutexLocker locker(&fMutexList); 
			ListElement *elem = NULL; 
			int theLengthSent = 0;
			if((elem = fMsgList.first) != NULL) 
			{ 
//				err = fSocket.Send((const void*)elem->content, elem->size, &theLengthSent);
				if (err == EAGAIN)
				{
					fSocket.RequestEvent(EV_RE | EV_WR);
				}
				else
				{
					ListRemoveHead(&fMsgList); 
					if(NULL != fMsgList.first)
						this->Signal(kWriteEvent);
				}
				
			}
			events -= Task::kWriteEvent;
		} 
		else if(events&Task::kZmqEvent)
		{	
			events -= Task::kZmqEvent;
		}
		else
		{
			return 0;
		}
	}
    
    // Make absolutely sure there are no resources being occupied by the session
    // at this point.
    this->CleanupRequest();

    // Only delete if it is ok to delete!
    if (fObjectHolders == 0)
        return -1;

    // If we are here because of a timeout, but we can't delete because someone
    // is holding onto a reference to this session, just reschedule the timeout.
    //
    // At this point, however, the session is DEAD.
    return 0;
}
Exemple #6
0
/**
 * Originates a new publication - sends it to all clients subscribed.
 * @param publish pointer to a stucture which contains all the publication information
 * @param originator the originating client
 */
void Protocol_processPublication(Publish* publish, char* originator)
{
	Messages* stored = NULL; /* to avoid duplication of data where possible */
	List* clients;
	ListElement* current = NULL;
	int savedMsgId = publish->msgId;
	int clean_needed = 0;

	FUNC_ENTRY;
	
	if (Topics_hasWildcards(publish->topic))
	{
		Log(LOG_INFO, 12, NULL, publish->topic, originator);
		goto exit;
	}

	if ((strcmp(INTERNAL_CLIENTID, originator) != 0) && bstate->password_file && bstate->acl_file)
	{
		Clients* client = (Clients*)(TreeFindIndex(bstate->clients, originator, 1)->content);
		
		if (Users_authorise(client->user, publish->topic, ACL_WRITE) == false)
		{
			Log(LOG_AUDIT, 149, NULL, originator, publish->topic);
			goto exit;
		}
	}

	if (publish->header.bits.retain)
	{
		SubscriptionEngines_setRetained(bstate->se, publish->topic, publish->header.bits.qos, publish->payload, publish->payloadlen);
		if (bstate->persistence == 1 && bstate->autosave_on_changes == 1 && bstate->autosave_interval > 0
			&& bstate->se->retained_changes >= bstate->autosave_interval)
		{
			Log(LOG_INFO, 100, NULL, bstate->autosave_interval);
			SubscriptionEngines_save(bstate->se);
		}
	}

	clients = SubscriptionEngines_getSubscribers(bstate->se, publish->topic, originator);
	if (strncmp(publish->topic, "$SYS/client/", 12) == 0)
	{ /* default subscription for a client */
		Node* node = TreeFindIndex(bstate->clients, &publish->topic[12], 1);
		if (node == NULL)
			node = TreeFind(bstate->disconnected_clients, &publish->topic[12]);
		if (node && node->content)
		{
			Subscriptions* rcs = malloc(sizeof(Subscriptions));
			rcs->clientName = &publish->topic[12];
			rcs->qos = 2;
			rcs->priority = PRIORITY_NORMAL;
			rcs->topicName = publish->topic;
			ListAppend(clients, rcs, sizeof(Subscriptions));
		}
	}
	current = NULL;
	while (ListNextElement(clients, &current))
	{
		Node* curnode = NULL;
		unsigned int qos = ((Subscriptions*)(current->content))->qos;
		int priority = ((Subscriptions*)(current->content))->priority;
		char* clientName = ((Subscriptions*)(current->content))->clientName;
		
		if (publish->header.bits.qos < qos) /* reduce qos if > subscribed qos */
			qos = publish->header.bits.qos;
			
		if ((curnode = TreeFindIndex(bstate->clients, clientName, 1)) == NULL)
			curnode = TreeFind(bstate->disconnected_clients, clientName);
#if defined(MQTTS)
		if (curnode == NULL && ((curnode = TreeFindIndex(bstate->mqtts_clients, clientName, 1)) == NULL))
			curnode = TreeFind(bstate->disconnected_mqtts_clients, clientName);
#endif

		if (curnode)
		{
			Clients* pubclient = (Clients*)(curnode->content);
			int retained = 0;
			Messages* saved = NULL;
			char* original_topic = publish->topic;
			
#if !defined(NO_BRIDGE)
			if (pubclient->outbound || pubclient->noLocal)
			{
				retained = publish->header.bits.retain; /* outbound and noLocal mean outward/inward bridge client,
																							so keep retained flag */
				if (pubclient->outbound)
				{
					Bridge_handleOutbound(pubclient, publish);
					if (publish->topic != original_topic)
					{ /* handleOutbound has changed the topic, so we musn't used the stored pub which
					        contains the original topic */
						saved = stored;
						stored = NULL;
					}
				}
			}
#endif
			if (Protocol_startOrQueuePublish(pubclient, publish, qos, retained, priority, &stored) == SOCKET_ERROR)
			{
				pubclient->good = pubclient->connected = 0; /* flag this client as needing to be cleaned up */
				clean_needed = 1;
			}
			if (publish->topic != original_topic)
			{
				stored = saved;  /* restore the stored pointer for the next loop iteration */
				free(publish->topic);
				publish->topic = original_topic;
			}
		}
	}
	publish->msgId = savedMsgId;
	/* INTERNAL_CLIENTID means that we are publishing data to the log,
			and we don't want to interfere with other close processing */
	if (clean_needed && strcmp(originator, INTERNAL_CLIENTID) != 0)
		MQTTProtocol_clean_clients(bstate->clients);
	ListFree(clients);
exit:
	FUNC_EXIT;
}
Exemple #7
0
/**
 * Create the server socket in multi-listener mode.
 * @param list pointer to a listener structure
 * @return completion code
 */
int Socket_addServerSocket(Listener* list)
{
	int flag = 1;
	int rc = SOCKET_ERROR;
	int ipv4 = 1; /* yes we can drop down to ipv4 */

	FUNC_ENTRY;
	if (!list->address || strcmp(list->address, "INADDR_ANY") == 0)
	{
		struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
		list->addr.sin_addr.s_addr = htonl(INADDR_ANY);
		list->addr6.sin6_addr = in6addr_any;
	}
	else
	{
		if (list->address[0] == '[')
		{
			int changed = ipv6_format(list->address);
#if defined(WIN32)
			/*wchar_t buf[(INET6_ADDRSTRLEN+1)*2];
			int buflen = sizeof(list->addr6);
			mbstowcs(buf, &list->address[1], sizeof(buf));
			rc = WSAStringToAddress(buf, AF_INET6, NULL, (struct sockaddr*)&list->addr6, &buflen);*/
			rc = win_inet_pton(AF_INET6, &list->address[1], &(list->addr6.sin6_addr));
#else
			rc = inet_pton(AF_INET6, &list->address[1], &(list->addr6.sin6_addr));
#endif
			ipv4 = 0;
			if (changed)
				(list->address)[changed] = ']';
		}
		else
		{
#if defined(WIN32)
			/*wchar_t buf[(INET6_ADDRSTRLEN+1)*2];
			int buflen = sizeof(list->addr);
			mbstowcs(buf, list->address, sizeof(buf));
			rc = WSAStringToAddress(buf, AF_INET, NULL, (struct sockaddr*)&list->addr, &buflen);*/
			rc = win_inet_pton(AF_INET, list->address, &(list->addr.sin_addr.s_addr));
#else
			rc = inet_pton(AF_INET, list->address, &(list->addr.sin_addr.s_addr));
#endif
			list->ipv6 = 0;
		}
#if defined(WIN32)
		if (rc != 0)
#else
		if (rc != 1)
#endif
		{
			Log(LOG_WARNING, 67, NULL, list->address);
			rc = -1;
			goto exit;
		}
	}
	list->socket = -1;
	if (list->protocol == PROTOCOL_MQTT)
	{
		if (list->ipv6)
			list->socket = socket(AF_INET6, SOCK_STREAM, 0);
		if (list->socket < 0 && ipv4)
		{
			list->socket = socket(AF_INET, SOCK_STREAM, 0);
			list->ipv6 = 0;
		}
	}
#if defined(MQTTS)
	else if (list->protocol == PROTOCOL_MQTTS)
	{
		if (list->ipv6)
			list->socket = socket(AF_INET6, SOCK_DGRAM, 0);
		if (list->socket < 0 && ipv4)
		{
			list->socket = socket(AF_INET, SOCK_DGRAM, 0);
			list->ipv6 = 0;
		}
	}
#endif
	Log(TRACE_MAX, 6, NULL, FD_SETSIZE);
	if (list->socket < 0)
	{
		Socket_error("socket", list->socket);
		Log(LOG_WARNING, 77, NULL);
		rc = list->socket;
		goto exit;
	}

#if !defined(WIN32)
	if (setsockopt(list->socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&flag, sizeof(int)) != 0)
		Log(LOG_WARNING, 109, NULL, list->port);
#endif
	if (list->ipv6)
	{
		list->addr6.sin6_family = AF_INET6;
		list->addr6.sin6_port = htons(list->port);
		rc = bind(list->socket, (struct sockaddr *)&(list->addr6), sizeof(list->addr6));
	}
	else
	{
		list->addr.sin_family = AF_INET;
		list->addr.sin_port = htons(list->port);
		memset(list->addr.sin_zero, 0, sizeof(list->addr.sin_zero));
		rc = bind(list->socket, (struct sockaddr *)&(list->addr), sizeof(list->addr));
	}
	if (rc == SOCKET_ERROR)
	{
		Socket_error("bind", list->socket);
		Log(LOG_WARNING, 78, NULL, list->port);
		goto exit;
	}

	/* Only listen if this is mqtt/tcp */
	if (list->protocol == PROTOCOL_MQTT &&
			listen(list->socket, SOMAXCONN) == SOCKET_ERROR) /* second parm is max no of connections */
	{
		Socket_error("listen", list->socket);
		Log(LOG_WARNING, 79, NULL, list->port);
		goto exit;
	}

	if (Socket_setnonblocking(list->socket) == SOCKET_ERROR)
	{
		Socket_error("setnonblocking", list->socket);
		goto exit;
	}

#if defined(MQTTS)
	/* If mqtts/udp, add to the list of clientsds to test for reading */
	if (list->protocol == PROTOCOL_MQTTS)
	{
		ListElement* current = NULL;
		int loopback = list->loopback;

#if !defined(USE_POLL)
		int* pnewSd = (int*)malloc(sizeof(list->socket));

		*pnewSd = list->socket;
		ListAppend(s.clientsds, pnewSd, sizeof(list->socket));
#endif
		Log(LOG_INFO, 300, NULL, list->port);

		if (setsockopt(list->socket, IPPROTO_IP, IP_MULTICAST_LOOP, (const char*)&loopback, sizeof(loopback)) == SOCKET_ERROR)
			Socket_error("set listener IP_MULTICAST_LOOP", list->socket);

		/* join any multicast groups */
		while (ListNextElement(list->multicast_groups, &current))
			Socket_joinMulticastGroup(list->socket, list->ipv6, (char*)(current->content));
	}
	else
#endif
		Log(LOG_INFO, 14, NULL, list->port);

#if defined(USE_POLL)
	/* add new socket to the epoll descriptor with epoll_ctl */
	struct socket_info* si = malloc(sizeof(struct socket_info));
	si->listener = list;
	si->fd = list->socket;
	si->connect_pending = 0;
	si->event.events = EPOLLIN;
	si->event.data.ptr = si;
	TreeAdd(s.fds_tree, si, sizeof(struct socket_info));
	if (epoll_ctl(s.epoll_fds, EPOLL_CTL_ADD, list->socket, &si->event) != 0)
		Socket_error("epoll_ctl add", list->socket);
#else
	FD_SET((u_int)list->socket, &(s.rset));         /* Add the current socket descriptor */
	s.maxfdp1 = max(s.maxfdp1+1, list->socket+1);

	memcpy((void*)&(s.rset_saved), (void*)&(s.rset), sizeof(s.rset_saved));
#endif

	rc = 0;
exit:
	FUNC_EXIT_RC(rc);
	return rc;
}
int MQTTClient_create(MQTTClient* handle, char* serverURI, char* clientId,
		int persistence_type, void* persistence_context)
{
	int rc = 0;
	MQTTClients *m = NULL;

	FUNC_ENTRY;
	rc = Thread_lock_mutex(mqttclient_mutex);

	if (serverURI == NULL || clientId == NULL)
	{
		rc = MQTTCLIENT_NULL_PARAMETER;
		goto exit;
	}

	if (!UTF8_validateString(clientId))
	{
		rc = MQTTCLIENT_BAD_UTF8_STRING;
		goto exit;
	}

	if (!initialized)
	{
		#if defined(HEAP_H)
			Heap_initialize();
		#endif
		Log_initialize();
		bstate->clients = ListInitialize();
		Socket_outInitialize();
		handles = ListInitialize();
		initialized = 1;
	}
	m = malloc(sizeof(MQTTClients));
	*handle = m;
	memset(m, '\0', sizeof(MQTTClients));
	if (strncmp(URI_TCP, serverURI, strlen(URI_TCP)) == 0)
		serverURI += strlen(URI_TCP);
	m->serverURI = malloc(strlen(serverURI)+1);
	strcpy(m->serverURI, serverURI);
	ListAppend(handles, m, sizeof(MQTTClients));

	m->c = malloc(sizeof(Clients));
	memset(m->c, '\0', sizeof(Clients));
	m->c->outboundMsgs = ListInitialize();
	m->c->inboundMsgs = ListInitialize();
	m->c->messageQueue = ListInitialize();
	m->c->clientID = malloc(strlen(clientId)+1);
	strcpy(m->c->clientID, clientId);
	m->connect_sem = Thread_create_sem();
	m->connack_sem = Thread_create_sem();
	m->suback_sem = Thread_create_sem();
	m->unsuback_sem = Thread_create_sem();

#if !defined(NO_PERSISTENCE)
	rc = MQTTPersistence_create(&(m->c->persistence), persistence_type, persistence_context);
	if (rc == 0)
		rc = MQTTPersistence_initialize(m->c, m->serverURI);
#endif
	ListAppend(bstate->clients, m->c, sizeof(Clients) + 3*sizeof(List));

exit:
	if (Thread_unlock_mutex(mqttclient_mutex) != 0)
		/* FFDC? */;
	FUNC_EXIT_RC(rc);
	return rc;
}
int MQTTClient_subscribeMany(MQTTClient handle, int count, char** topic, int* qos)
{
	MQTTClients* m = handle;
	List* topics = ListInitialize();
	List* qoss = ListInitialize();
	int i = 0;
	int rc = MQTTCLIENT_FAILURE;

	FUNC_ENTRY;
	Thread_lock_mutex(mqttclient_mutex);

	if (m == NULL || m->c == NULL)
	{
		rc = MQTTCLIENT_FAILURE;
		goto exit;
	}
	if (m->c->connected == 0)
	{
		rc = MQTTCLIENT_DISCONNECTED;
		goto exit;
	}
	for (i = 0; i < count; i++)
	{
		if (!UTF8_validateString(topic[i]))
		{
			rc = MQTTCLIENT_BAD_UTF8_STRING;
			goto exit;
		}
	}

	for (i = 0; i < count; i++)
	{
		ListAppend(topics, topic[i], strlen(topic[i]));
		ListAppend(qoss, &qos[i], sizeof(int));
	}
	rc = MQTTProtocol_subscribe(m->c, topics, qoss);
	ListFreeNoContent(topics);
	ListFreeNoContent(qoss);

	if (rc == TCPSOCKET_COMPLETE)
	{
		MQTTPacket* pack = NULL;

		Thread_unlock_mutex(mqttclient_mutex);
		pack = MQTTClient_waitfor(handle, SUBACK, &rc, 10000L);
		Thread_lock_mutex(mqttclient_mutex);
		if (pack != NULL)
		{
			rc = MQTTProtocol_handleSubacks(pack, m->c->socket);
			m->pack = NULL;
		}
		else
			rc = SOCKET_ERROR;
	}

	if (rc == SOCKET_ERROR)
	{
		Thread_unlock_mutex(mqttclient_mutex);
		MQTTClient_disconnect_internal(handle, 0);
		Thread_lock_mutex(mqttclient_mutex);
	}
	else if (rc == TCPSOCKET_COMPLETE)
		rc = MQTTCLIENT_SUCCESS;

exit:
	Thread_unlock_mutex(mqttclient_mutex);
	FUNC_EXIT_RC(rc);
	return rc;
}
Exemple #10
0
static void AssignOpcodes(FILE *f)
{
	List *group1 = ListAppend(NULL, 0);
	int i;
	
	for (i = 1; i < N1; i++)
		ListAppend(group1, i);
	
	ADD2 = PopRandomOpcode1(&group1);
	ADD4 = PopRandomOpcode1(&group1);
	ADDC2 = PopRandomOpcode1(&group1);
	ADDC4 = PopRandomOpcode1(&group1);
	ANL2 = PopRandomOpcode1(&group1);
	ANL4 = PopRandomOpcode1(&group1);
	ANL5 = PopRandomOpcode1(&group1);
	ANL6 = PopRandomOpcode1(&group1);
	ANL7 = PopRandomOpcode1(&group1);
	ANL8 = PopRandomOpcode1(&group1);
	CJNE1 = PopRandomOpcode1(&group1);
	CJNE2 = PopRandomOpcode1(&group1);
	CLR1 = PopRandomOpcode1(&group1);
	CLR2 = PopRandomOpcode1(&group1);
	CLR3 = PopRandomOpcode1(&group1);
	CPL1 = PopRandomOpcode1(&group1);
	CPL2 = PopRandomOpcode1(&group1);
	CPL3 = PopRandomOpcode1(&group1);
	DA = PopRandomOpcode1(&group1);
	DEC1 = PopRandomOpcode1(&group1);
	DEC3 = PopRandomOpcode1(&group1);
	DIV = PopRandomOpcode1(&group1);
	DJNZ2 = PopRandomOpcode1(&group1);
	INC1 = PopRandomOpcode1(&group1);
	INC3 = PopRandomOpcode1(&group1);
	INC5 = PopRandomOpcode1(&group1);
	JB = PopRandomOpcode1(&group1);
	JBC = PopRandomOpcode1(&group1);
	JC = PopRandomOpcode1(&group1);
	JMP = PopRandomOpcode1(&group1);
	JNB = PopRandomOpcode1(&group1);
	JNC = PopRandomOpcode1(&group1);
	JNZ = PopRandomOpcode1(&group1);
	JZ = PopRandomOpcode1(&group1);
	LCALL = PopRandomOpcode1(&group1);
	LJMP = PopRandomOpcode1(&group1);
	MOV2 = PopRandomOpcode1(&group1);
	MOV4 = PopRandomOpcode1(&group1);
	MOV8 = PopRandomOpcode1(&group1);
	MOV10 = PopRandomOpcode1(&group1);
	MOV12 = PopRandomOpcode1(&group1);
	MOV16 = PopRandomOpcode1(&group1);
	MOV17 = PopRandomOpcode1(&group1);
	MOV18 = PopRandomOpcode1(&group1);
	MOVC1 = PopRandomOpcode1(&group1);
	MOVC2 = PopRandomOpcode1(&group1);
	MOVX2 = PopRandomOpcode1(&group1);
	MOVX4 = PopRandomOpcode1(&group1);
	MUL = PopRandomOpcode1(&group1);
	ORL2 = PopRandomOpcode1(&group1);
	ORL4 = PopRandomOpcode1(&group1);
	ORL5 = PopRandomOpcode1(&group1);
	ORL6 = PopRandomOpcode1(&group1);
	ORL7 = PopRandomOpcode1(&group1);
	ORL8 = PopRandomOpcode1(&group1);
	POP = PopRandomOpcode1(&group1);
	PUSH = PopRandomOpcode1(&group1);
	RET = PopRandomOpcode1(&group1);
	RL = PopRandomOpcode1(&group1);
	RLC = PopRandomOpcode1(&group1);
	RR = PopRandomOpcode1(&group1);
	RRC = PopRandomOpcode1(&group1);
	SETB1 = PopRandomOpcode1(&group1);
	SETB2 = PopRandomOpcode1(&group1);
	SJMP = PopRandomOpcode1(&group1);
	SUBB2 = PopRandomOpcode1(&group1);
	SUBB4 = PopRandomOpcode1(&group1);
	SWAP = PopRandomOpcode1(&group1);
	XCH2 = PopRandomOpcode1(&group1);
	XRL2 = PopRandomOpcode1(&group1);
	XRL4 = PopRandomOpcode1(&group1);
	XRL5 = PopRandomOpcode1(&group1);
	XRL6 = PopRandomOpcode1(&group1);
	
	group1 = ListAppend(NULL, 0);
	for (i = 1; i < N2; i++)
		ListAppend(group1, i);
	
	ADD3 = PopRandomOpcode2(&group1);
	ADDC3 = PopRandomOpcode2(&group1);
	ANL3 = PopRandomOpcode2(&group1);
	CJNE4 = PopRandomOpcode2(&group1);
	DEC4 = PopRandomOpcode2(&group1);
	INC4 = PopRandomOpcode2(&group1);
	MOV3 = PopRandomOpcode2(&group1);
	MOV11 = PopRandomOpcode2(&group1);
	MOV13 = PopRandomOpcode2(&group1);
	MOV14 = PopRandomOpcode2(&group1);
	MOV15 = PopRandomOpcode2(&group1);
	MOVX1 = PopRandomOpcode2(&group1);
	MOVX3 = PopRandomOpcode2(&group1);
	ORL3 = PopRandomOpcode2(&group1);
	SUBB3 = PopRandomOpcode2(&group1);
	XCH3 = PopRandomOpcode2(&group1);
	XCHD = PopRandomOpcode2(&group1);
	XRL3 = PopRandomOpcode2(&group1);
	
	
	group1 = ListAppend(NULL, 0);
	for (i = 1; i < N3; i++)
		ListAppend(group1, i);
	
	ADD1 = PopRandomOpcode3(&group1);
	ADDC1 = PopRandomOpcode3(&group1);
	ANL1 = PopRandomOpcode3(&group1);
	CJNE3 = PopRandomOpcode3(&group1);
	DEC2 = PopRandomOpcode3(&group1);
	DJNZ1 = PopRandomOpcode3(&group1);
	INC2 = PopRandomOpcode3(&group1);
	MOV1 = PopRandomOpcode3(&group1);
	MOV5 = PopRandomOpcode3(&group1);
	MOV6 = PopRandomOpcode3(&group1);
	MOV7 = PopRandomOpcode3(&group1);
	MOV9 = PopRandomOpcode3(&group1);
	ORL1 = PopRandomOpcode3(&group1);
	SUBB1 = PopRandomOpcode3(&group1);
	XRL1 = PopRandomOpcode3(&group1);
	XCH1 = PopRandomOpcode3(&group1);
	
	group1 = ListAppend(NULL, 0);
	for (i = 1; i < N4; i++)
		ListAppend(group1, i);
	
	ACALL = PopRandomOpcode4(&group1);
	AJMP = PopRandomOpcode4(&group1);
	
	ANL2_X = rand();
	ANL4_X = rand();
	ANL5_X = rand();
	ANL6_X1 = rand();
	ANL6_X2 = rand();
	ANL7_X = rand();
	ANL8_X = rand();
	ORL2_X = rand();
	ORL4_X = rand();
	ORL5_X = rand();
	ORL6_X1 = rand();
	ORL6_X2 = rand();
	ORL7_X = rand();
	ORL8_X = rand();
	XRL2_X = rand();
	XRL4_X = rand();
	XRL5_X = rand();
	XRL6_X1 = rand();
	XRL6_X2 = rand();
	CLR3_X = rand();
	SETB2_X = rand();
	CPL3_X = rand();
	XCH2_X = rand();
	LCALL_X1 = rand();
	LCALL_X2 = rand();
	ACALL_X = rand();
	CJNE1_X1 = rand();
	CJNE1_X2  = rand();
	CJNE2_X1 = rand();
	CJNE2_X2 = rand();
	CJNE3_X1 = rand();
	CJNE3_X2 = rand();
	CJNE4_X1 = rand();
	CJNE4_X2 = rand();
	DEC3_X = rand();
	INC3_X = rand();
	DJNZ1_X = rand();
	DJNZ2_X1 = rand();
	DJNZ2_X2 = rand();
	POP_X = rand();
	PUSH_X = rand();
	JB_X1 = rand();
	JB_X2 = rand();
	JBC_X1 = rand();
	JBC_X2 = rand();
	JC_X = rand();
	JNB_X1 = rand();
	JNB_X2 = rand();
	JNC_X = rand();
	JNZ_X = rand();
	JZ_X = rand();
	AJMP_X = rand();
	LJMP_X1 = rand();
	LJMP_X2 = rand();
	SJMP_X = rand();
	MOV2_X = rand();
	MOV4_X = rand();
	MOV6_X = rand();
	MOV7_X = rand();
	MOV8_X = rand();
	MOV9_X = rand();
	MOV10_X1 = rand();
	MOV10_X2 = rand();
	MOV11_X = rand();
	MOV12_X1 = rand();
	MOV12_X2 = rand();
	MOV14_X = rand();
	MOV15_X = rand();
	MOV16_X = rand();
	MOV17_X = rand();
	MOV18_X1 = rand();
	MOV18_X2 = rand();
	ADD2_X = rand();
	ADD4_X = rand();
	ADDC2_X = rand();
	ADDC4_X = rand();
	SUBB2_X = rand();
	SUBB4_X = rand();
	
	group1 = ListAppend2(NULL, ADD2, "ADD2");
	ListAppend2(group1, ADD4, "ADD4");
	ListAppend2(group1, ADDC2, "ADDC2");
	ListAppend2(group1, ADDC4, "ADDC4");
	ListAppend2(group1, ANL2, "ANL2");
	ListAppend2(group1, ANL4, "ANL4");
	ListAppend2(group1, ANL5, "ANL5");
	ListAppend2(group1, ANL6, "ANL6");
	ListAppend2(group1, ANL7, "ANL7");
	ListAppend2(group1, ANL8, "ANL8");
	ListAppend2(group1, CJNE1, "CJNE1");
	ListAppend2(group1, CJNE2, "CJNE2");
	ListAppend2(group1, CLR1, "CLR1");
	ListAppend2(group1, CLR2, "CLR2");
	ListAppend2(group1, CLR3, "CLR3");
	ListAppend2(group1, CPL1, "CPL1");
	ListAppend2(group1, CPL2, "CPL2");
	ListAppend2(group1, CPL3, "CPL3");
	ListAppend2(group1, DA, "DA");
	ListAppend2(group1, DEC1, "DEC1");
	ListAppend2(group1, DEC3, "DEC3");
	ListAppend2(group1, DIV, "DIV");
	ListAppend2(group1, DJNZ2, "DJNZ2");
	ListAppend2(group1, INC1, "INC1");
	ListAppend2(group1, INC3, "INC3");
	ListAppend2(group1, INC5, "INC5");
	ListAppend2(group1, JB, "JB");
	ListAppend2(group1, JBC, "JBC");
	ListAppend2(group1, JC, "JC");
	ListAppend2(group1, JMP, "JMP");
	ListAppend2(group1, JNB, "JNB");
	ListAppend2(group1, JNC, "JNC");
	ListAppend2(group1, JNZ, "JNZ");
	ListAppend2(group1, JZ, "JZ");
	ListAppend2(group1, LCALL, "LCALL");
	ListAppend2(group1, LJMP, "LJMP");
	ListAppend2(group1, MOV2, "MOV2");
	ListAppend2(group1, MOV4, "MOV4");
	ListAppend2(group1, MOV8, "MOV8");
	ListAppend2(group1, MOV10, "MOV10");
	ListAppend2(group1, MOV12, "MOV12");
	ListAppend2(group1, MOV16, "MOV16");
	ListAppend2(group1, MOV17, "MOV17");
	ListAppend2(group1, MOV18, "MOV18");
	ListAppend2(group1, MOVC1, "MOVC1");
	ListAppend2(group1, MOVC2, "MOVC2");
	ListAppend2(group1, MOVX2, "MOVX2");
	ListAppend2(group1, MOVX4, "MOVX4");
	ListAppend2(group1, MUL, "MUL");
	ListAppend2(group1, ORL2, "ORL2");
	ListAppend2(group1, ORL4, "ORL4");
	ListAppend2(group1, ORL5, "ORL5");
	ListAppend2(group1, ORL6, "ORL6");
	ListAppend2(group1, ORL7, "ORL7");
	ListAppend2(group1, ORL8, "ORL8");
	ListAppend2(group1, POP, "POP");
	ListAppend2(group1, PUSH, "PUSH");
	ListAppend2(group1, RET, "RET");
	ListAppend2(group1, RL, "RL");
	ListAppend2(group1, RLC, "RLC");
	ListAppend2(group1, RR, "RR");
	ListAppend2(group1, RRC, "RRC");
	ListAppend2(group1, SETB1, "SETB1");
	ListAppend2(group1, SETB2, "SETB2");
	ListAppend2(group1, SJMP, "SJMP");
	ListAppend2(group1, SUBB2, "SUBB2");
	ListAppend2(group1, SUBB4, "SUBB4");
	ListAppend2(group1, SWAP, "SWAP");
	ListAppend2(group1, XCH2, "XCH2");
	ListAppend2(group1, XRL2, "XRL2");
	ListAppend2(group1, XRL4, "XRL4");
	ListAppend2(group1, XRL5, "XRL5");
	ListAppend2(group1, XRL6, "XRL6");
	ListAppend2(group1, ADD3, "ADD3");
	ListAppend2(group1, ADDC3, "ADDC3");
	ListAppend2(group1, ANL3, "ANL3");
	ListAppend2(group1, CJNE4, "CJNE4");
	ListAppend2(group1, DEC4, "DEC4");
	ListAppend2(group1, INC4, "INC4");
	ListAppend2(group1, MOV3, "MOV3");
	ListAppend2(group1, MOV11, "MOV11");
	ListAppend2(group1, MOV13, "MOV13");
	ListAppend2(group1, MOV14, "MOV14");
	ListAppend2(group1, MOV15, "MOV15");
	ListAppend2(group1, MOVX1, "MOVX1");
	ListAppend2(group1, MOVX3, "MOVX3");
	ListAppend2(group1, ORL3, "ORL3");
	ListAppend2(group1, SUBB3, "SUBB3");
	ListAppend2(group1, XCH3, "XCH3");
	ListAppend2(group1, XCHD, "XCHD");
	ListAppend2(group1, XRL3, "XRL3");
	ListAppend2(group1, ADD1, "ADD1");
	ListAppend2(group1, ADDC1, "ADDC1");
	ListAppend2(group1, ANL1, "ANL1");
	ListAppend2(group1, CJNE3, "CJNE3");
	ListAppend2(group1, DEC2, "DEC2");
	ListAppend2(group1, DJNZ1, "DJNZ1");
	ListAppend2(group1, INC2, "INC2");
	ListAppend2(group1, MOV1, "MOV1");
	ListAppend2(group1, MOV5, "MOV5");
	ListAppend2(group1, MOV6, "MOV6");
	ListAppend2(group1, MOV7, "MOV7");
	ListAppend2(group1, MOV9, "MOV9");
	ListAppend2(group1, ORL1, "ORL1");
	ListAppend2(group1, SUBB1, "SUBB1");
	ListAppend2(group1, XRL1, "XRL1");
	ListAppend2(group1, XCH1, "XCH1");
	ListAppend2(group1, ACALL, "ACALL");
	ListAppend2(group1, AJMP, "AJMP");
	ListAppend2(group1, ANL2_X, "ANL2_X");
	ListAppend2(group1, ANL4_X, "ANL4_X");
	ListAppend2(group1, ANL5_X, "ANL5_X");
	ListAppend2(group1, ANL6_X1, "ANL6_X1");
	ListAppend2(group1, ANL6_X2, "ANL6_X2");
	ListAppend2(group1, ANL7_X, "ANL7_X");
	ListAppend2(group1, ANL8_X, "ANL8_X");
	ListAppend2(group1, ORL2_X, "ORL2_X");
	ListAppend2(group1, ORL4_X, "ORL4_X");
	ListAppend2(group1, ORL5_X, "ORL5_X");
	ListAppend2(group1, ORL6_X1,"ORL6_X1");
	ListAppend2(group1, ORL6_X2, "ORL6_X2");
	ListAppend2(group1, ORL7_X, "ORL7_X");
	ListAppend2(group1, ORL8_X, "ORL8_X");
	ListAppend2(group1, XRL2_X, "XRL2_X");
	ListAppend2(group1, XRL4_X, "XRL4_X");
	ListAppend2(group1, XRL5_X, "XRL5_X");
	ListAppend2(group1, XRL6_X1, "XRL6_X1");
	ListAppend2(group1, XRL6_X2, "XRL6_X2");
	ListAppend2(group1, CLR3_X, "CLR3_X");
	ListAppend2(group1, SETB2_X, "SETB2_X");
	ListAppend2(group1, CPL3_X, "CPL3_X");
	ListAppend2(group1, XCH2_X, "XCH2_X");
	ListAppend2(group1, LCALL_X1, "LCALL_X1");
	ListAppend2(group1, LCALL_X2, "LCALL_X2");
	ListAppend2(group1, ACALL_X, "ACALL_X");
	ListAppend2(group1, CJNE1_X1, "CJNE1_X1");
	ListAppend2(group1, CJNE1_X2, "CJNE1_X2");
	ListAppend2(group1, CJNE2_X1, "CJNE2_X1");
	ListAppend2(group1, CJNE2_X2, "CJNE2_X2");
	ListAppend2(group1, CJNE3_X1, "CJNE3_X1");
	ListAppend2(group1, CJNE3_X2, "CJNE3_X2");
	ListAppend2(group1, CJNE4_X1, "CJNE4_X1");
	ListAppend2(group1, CJNE4_X2, "CJNE4_X2");
	ListAppend2(group1, DEC3_X, "DEC3_X");
	ListAppend2(group1, INC3_X, "INC3_X");
	ListAppend2(group1, DJNZ1_X, "DJNZ1_X");
	ListAppend2(group1, DJNZ2_X1, "DJNZ2_X1");
	ListAppend2(group1, DJNZ2_X2, "DJNZ2_X2");
	ListAppend2(group1, POP_X, "POP_X");
	ListAppend2(group1, PUSH_X, "PUSH_X");
	ListAppend2(group1, JB_X1, "JB_X1");
	ListAppend2(group1, JB_X2, "JB_X2");
	ListAppend2(group1, JBC_X1, "JBC_X1");
	ListAppend2(group1, JBC_X2, "JBC_X2");
	ListAppend2(group1, JC_X, "JC_X");
	ListAppend2(group1, JNB_X1, "JNB_X1");
	ListAppend2(group1, JNB_X2, "JNB_X2");
	ListAppend2(group1, JNC_X, "JNC_X");
	ListAppend2(group1, JNZ_X, "JNZ_X");
	ListAppend2(group1, JZ_X, "JZ_X");
	ListAppend2(group1, AJMP_X, "AJMP_X");
	ListAppend2(group1, LJMP_X1, "LJMP_X1");
	ListAppend2(group1, LJMP_X2, "LJMP_X2");
	ListAppend2(group1, SJMP_X, "SJMP_X");
	ListAppend2(group1, MOV2_X, "MOV2_X");
	ListAppend2(group1, MOV4_X, "MOV4_X");
	ListAppend2(group1, MOV6_X, "MOV6_X");
	ListAppend2(group1, MOV7_X, "MOV7_X");
	ListAppend2(group1, MOV8_X, "MOV8_X");
	ListAppend2(group1, MOV9_X, "MOV9_X");
	ListAppend2(group1, MOV10_X1, "MOV10_X1");
	ListAppend2(group1, MOV10_X2, "MOV10_X2");
	ListAppend2(group1, MOV11_X, "MOV11_X");
	ListAppend2(group1, MOV12_X1, "MOV12_X1");
	ListAppend2(group1, MOV12_X2, "MOV12_X2");
	ListAppend2(group1, MOV14_X, "MOV14_X");
	ListAppend2(group1, MOV15_X, "MOV15_X");
	ListAppend2(group1, MOV16_X, "MOV16_X");
	ListAppend2(group1, MOV17_X, "MOV17_X");
	ListAppend2(group1, MOV18_X1, "MOV18_X1");
	ListAppend2(group1, MOV18_X2, "MOV18_X2");
	ListAppend2(group1, ADD2_X, "ADD2_X");
	ListAppend2(group1, ADD4_X, "ADD4_X");
	ListAppend2(group1, ADDC2_X, "ADDC2_X");
	ListAppend2(group1, ADDC4_X, "ADDC4_X");
	ListAppend2(group1, SUBB2_X, "SUBB2_X");
	ListAppend2(group1, SUBB4_X, "SUBB4_X");
	
	int n = GetListLength(group1);
	
	for (i = 0; i < n; i++)
	{
		uint8_t opcode;
		const char *name = PopRandomOpcode(&group1, &opcode);
		
		fprintf(f, "static uint8_t %s = 0x%02X;\n", name, opcode);
	}
}
Exemple #11
0
void *YAsyncBytes(long n)
{
  void *ptr= p_malloc(n);
  return keeplist? ListAppend(ptr) : ptr;
}
Exemple #12
0
int InvokeProgram(int oftype)
{
	List p = NULL;
	char **cmd;
	char *file;
	int status = 0;

	switch (oftype)
	{
	case PP_FILE:
		if (Option.cfiles == NULL)
			return 0;

		for (p = Option.cfiles; p != NULL; p = p->next)
		{
			PPFiles = ListAppend(PPFiles, FileName(p->str, ".i"));	
		}

		Option.pfiles = ListCombine(Option.pfiles, PPFiles);
		cmd = BuildCommand(CPPProg, Option.pflags, Option.cfiles, PPFiles);
		status = _spawnvp(_P_WAIT, cmd[0], cmd);

		for (p = PPFiles; p != NULL; p = p->next)
		{
			if ((file = strrchr(p->str, '\\')) || (file = strrchr(p->str, '/')))
			{
				rename(file + 1, p->str);
			}
		}
		break;

	case ASM_FILE:
		if (Option.pfiles == NULL)
			return 0;

		for (p = Option.pfiles; p != NULL; p = p->next)
		{
			ASMFiles = ListAppend(ASMFiles, FileName(p->str, ".asm"));
		}

		Option.afiles = ListCombine(Option.afiles, ASMFiles);
		cmd = BuildCommand(CCProg, Option.cflags, Option.pfiles, ASMFiles);
		status = _spawnvp(_P_WAIT, cmd[0], cmd);
		break;

	case OBJ_FILE:
		if (Option.afiles == NULL)
			return 0;

		for (p = Option.aflags, Option.aflags = NULL; p != NULL; p = p->next)
		{
			Option.aflags = ListCombine(Option.aflags, ParseOption(p->str + 4));
		}
		for (p = Option.afiles; p != NULL; p = p->next)
		{
			file = FileName(p->str, ".obj");
			OBJFiles = ListAppend(OBJFiles, file);
			cmd = BuildCommand(ASProg, Option.aflags, ListAppend(NULL, p->str), ListAppend(NULL, file));
			status = _spawnvp(_P_WAIT, cmd[0], cmd);
		}
		Option.ofiles = ListCombine(Option.ofiles, OBJFiles);
		break;

	case LIB_FILE:
		break;

	case EXE_FILE:
		if (Option.ofiles == NULL)
			return 0;

		if (Option.out == NULL)
		{
			Option.out = Option.ofiles->str;
		}
		Option.out = FileName(Option.out, ".exe");
		for (p = Option.lflags, Option.lflags = NULL; p != NULL; p = p->next)
		{
			Option.lflags = ListCombine(Option.lflags, ParseOption(p->str + 4));
		}
		cmd = BuildCommand(LDProg, Option.lflags, Option.linput, ListAppend(NULL, Option.out));
		status = _spawnvp(_P_WAIT, cmd[0], cmd);
		break;
	}

	return status;
}
Exemple #13
0
void KernelStart(char *cmd_args[], unsigned int pmem_size, UserContext *uctxt) {
    virtual_memory_enabled = false;

    next_synch_resource_id = 1;

    // Initialize the interrupt vector table and write the base address
    // to the REG_VECTOR_BASE register
    TrapTableInit();

    // Create the idle proc
    UserContext model_user_context = *uctxt;
    idle_proc = NewBlankPCB(model_user_context);

    // Perform the malloc for the idle proc's kernel stack page table before making page tables.
    idle_proc->kernel_stack_page_table =
            (struct pte *) calloc(KERNEL_STACK_MAXSIZE / PAGESIZE, sizeof(struct pte));

    // Build the initial page table for region 0 such that page = frame for all valid pages.
    region_0_page_table = (struct pte *) calloc(VMEM_0_SIZE / PAGESIZE, sizeof(struct pte));

    // Create the idle proc's page table for region 1.
    CreateRegion1PageTable(idle_proc);

    // Create the PTEs for the kernel text and data with the proper protections.
    unsigned int i;
    for (i = 0; i < kernel_brk_page; i++) {
        region_0_page_table[i].valid = 1;
        region_0_page_table[i].pfn = i;

        if (i < kernel_data_start_page) { // Text section.
            region_0_page_table[i].prot = PROT_READ | PROT_EXEC;
        } else { // Data section.
            region_0_page_table[i].prot = PROT_READ | PROT_WRITE;
        }
    }

    // Create the PTEs for the idle proc's kernel stack with page = frame and the proper protections.
    unsigned int kernel_stack_base_page = ADDR_TO_PAGE(KERNEL_STACK_BASE);
    for (i = 0; i < NUM_KERNEL_PAGES; i++) {
        idle_proc->kernel_stack_page_table[i].valid = 1;
        idle_proc->kernel_stack_page_table[i].pfn = i + kernel_stack_base_page;

        idle_proc->kernel_stack_page_table[i].prot = PROT_READ | PROT_WRITE;
    }
    // Load this new page table
    UseKernelStackForProc(idle_proc);
    idle_proc->kernel_context_initialized = true;

    // Set the TLB registers for the region 0 page table.
    WriteRegister(REG_PTBR0, (unsigned int) region_0_page_table);
    WriteRegister(REG_PTLR0, VMEM_0_SIZE / PAGESIZE);

    // Set the TLB registers for the region 1 page table.
    WriteRegister(REG_PTBR1, (unsigned int) idle_proc->region_1_page_table);
    WriteRegister(REG_PTLR1, VMEM_1_SIZE / PAGESIZE);

    // Enable virtual memory. Wooooo!
    TracePrintf(TRACE_LEVEL_DETAIL_INFO, "Enabling virtual memory. Wooooo!\n");
    virtual_memory_enabled = true;
    WriteRegister(REG_VM_ENABLE, 1);

    // Initialize the physical memory management data structures. Then, initialize the
    // kernel book keeping structs.

    // Make idle the current proc since it has a region 1 page table that this call can use.
    current_proc = idle_proc;

    InitializePhysicalMemoryManagement(pmem_size);
    InitBookkeepingStructs();

    int rc = LoadProgram("idle", NULL, idle_proc);
    if (rc != SUCCESS) {
        TracePrintf(TRACE_LEVEL_TERMINAL_PROBLEM, "KernelStart: FAILED TO LOAD IDLE!!\n");
        Halt();
    }

    // Load the init program.
    char *init_program_name = "init";
    if (cmd_args[0]) {
        init_program_name = cmd_args[0];
    }
    // Load the init program, but first make sure we are pointing to its region 1 page table.
    PCB *init_proc = NewBlankPCBWithPageTables(model_user_context);
    WriteRegister(REG_PTBR1, (unsigned int) init_proc->region_1_page_table);
    WriteRegister(REG_TLB_FLUSH, TLB_FLUSH_1);
    rc = LoadProgram(init_program_name, cmd_args, init_proc);
    if (rc != SUCCESS) {
        TracePrintf(TRACE_LEVEL_TERMINAL_PROBLEM, "KernelStart: FAILED TO LOAD INIT!!\n");
        Halt();
    }

    // Make idle the current proc.
    current_proc = idle_proc;
    WriteRegister(REG_PTBR1, (unsigned int) idle_proc->region_1_page_table);
    WriteRegister(REG_TLB_FLUSH, TLB_FLUSH_1);

    // Place the init proc in the ready queue.
    // On the first clock tick, the init process will be initialized and ran.
    ListAppend(ready_queue, init_proc, init_proc->pid);

    // Use the idle proc's user context after returning from KernelStart().
    *uctxt = idle_proc->user_context;
}
Exemple #14
0
/* No SSL_writev() provided by OpenSSL. Boo. */  
int SSLSocket_putdatas(SSL* ssl, int socket, char* buf0, size_t buf0len, int count, char** buffers, size_t* buflens, int* frees)
{
	int rc = 0;
	int i;
	char *ptr;
	iobuf iovec;
	int sslerror;

	FUNC_ENTRY;
	iovec.iov_len = buf0len;
	for (i = 0; i < count; i++)
		iovec.iov_len += buflens[i];

	ptr = iovec.iov_base = (char *)malloc(iovec.iov_len);  
	memcpy(ptr, buf0, buf0len);
	ptr += buf0len;
	for (i = 0; i < count; i++)
	{
		memcpy(ptr, buffers[i], buflens[i]);
		ptr += buflens[i];
	}

	SSL_lock_mutex(&sslCoreMutex);
	if ((rc = SSL_write(ssl, iovec.iov_base, iovec.iov_len)) == iovec.iov_len)
		rc = TCPSOCKET_COMPLETE;
	else 
	{ 
		sslerror = SSLSocket_error("SSL_write", ssl, socket, rc);
		
		if (sslerror == SSL_ERROR_WANT_WRITE)
		{
			int* sockmem = (int*)malloc(sizeof(int));
			int free = 1;

			Log(TRACE_MIN, -1, "Partial write: incomplete write of %d bytes on SSL socket %d",
				iovec.iov_len, socket);
			SocketBuffer_pendingWrite(socket, ssl, 1, &iovec, &free, iovec.iov_len, 0);
			*sockmem = socket;
			ListAppend(s.write_pending, sockmem, sizeof(int));
			FD_SET(socket, &(s.pending_wset));
			rc = TCPSOCKET_INTERRUPTED;
		}
		else 
			rc = SOCKET_ERROR;
	}
	SSL_unlock_mutex(&sslCoreMutex);

	if (rc != TCPSOCKET_INTERRUPTED)
		free(iovec.iov_base);
	else
	{
		int i;
		free(buf0);
		for (i = 0; i < count; ++i)
		{
			if (frees[i])
				free(buffers[i]);
		}	
	}
	FUNC_EXIT_RC(rc); 
	return rc;
}
Exemple #15
0
static int Parse( char *Cmd )
/***************************/
{
    char        opt;
    char        *end;
    FILE        *atfp;
    char        buffer[_MAX_PATH];
    char        unquoted[_MAX_PATH];
    size_t      len;
    char        *p;
    int         wcc_option;
    list        *new_item;

    /* Cmd will always begin with at least one */
    /* non-space character if we get this far  */

    for( ;; ) {
        Cmd = SkipSpaces( Cmd );
        if( *Cmd == '\0' )
            break;
        opt = *Cmd;
        if( opt == '-'  ||  opt == Switch_Chars[1] ) {
            Cmd++;
        } else if( opt != '@' ) {
            opt = ' ';
        }

        end = Cmd;
        if( *Cmd == '"' ) {
            end = FindNextWS( end );
        } else {
            end = FindNextWSOrOpt( end, opt, Switch_Chars );
        }
        len = end - Cmd;
        if( len != 0 ) {
            if( opt == ' ' ) {          /* if filename, add to list */
                strncpy( Word, Cmd, len );
                Word[len] = '\0';
                end = ScanFName( end, len );
                UnquoteFName( unquoted, sizeof( unquoted ), Word );
                new_item = MemAlloc( sizeof( list ) );
                new_item->next = NULL;
                new_item->item = MemStrDup( unquoted );
                if( FileExtension( Word, ".lib" ) ) {
                    ListAppend( &Libs_List, new_item );
                } else if( FileExtension( Word, ".res" ) ) {
                    ListAppend( &Res_List, new_item );
                } else {
                    ListAppend( &Files_List, new_item );
                }
            } else {                    /* otherwise, do option */
                --len;
                strncpy( Word, Cmd + 1, len );
                Word[len] = '\0';
                wcc_option = 1;         /* assume it's a wcc option */

                switch( tolower( *Cmd ) ) {
                case 'b':               /* possibly -bcl */
                    if( strnicmp( Word, "cl=", 3 ) == 0 ) {
                        strcat( CC_Opts, " -bt=" );
                        strcat( CC_Opts, Word+3 );
                        Flags.link_for_sys = TRUE;
                        MemFree( SystemName );
                        SystemName = MemStrDup( Word+3 );
                        wcc_option = 0;
                    }
                    break;

                case 'f':               /* files option */
                    p = ScanFName( end, len );
                    switch( tolower( Word[0] ) ) {
                    case 'd':           /* name of linker directive file */
                        if( Word[1] == '='  ||  Word[1] == '#' ) {
                            end = p;
                            /* remove quotes from target linker control filename */
                            UnquoteFName( unquoted, sizeof( unquoted ), Word + 2 );

                            MakeName( unquoted, ".lnk" );    /* add extension */

                            MemFree( Link_Name );
                            Link_Name = MemStrDup( unquoted );
                        } else {
                            MemFree( Link_Name );
                            Link_Name = MemStrDup( TEMPFILE );
                        }
                        wcc_option = 0;
                        break;
                    case 'e':           /* name of exe file */
                        if( Word[1] == '='  ||  Word[1] == '#' ) {
                            end = p;
                            /* remove quotes from target executable filename */
                            UnquoteFName( unquoted, sizeof( unquoted ), Word + 2 );
                            strcpy( Exe_Name, unquoted );
                        }
                        wcc_option = 0;
                        break;
                    case 'i':           /* name of forced include file */
                        end = p;
                        break;
                    case 'm':           /* name of map file */
                        Flags.map_wanted = TRUE;
                        if( Word[1] == '='  ||  Word[1] == '#' ) {
                            end = p;
                            /* remove quotes from target map filename */
                            UnquoteFName( unquoted, sizeof( unquoted ), Word + 2 );

                            MemFree( Map_Name );
                            Map_Name = MemStrDup( unquoted );
                        }
                        wcc_option = 0;
                        break;
                    case 'o':           /* name of object file */
                        end = p;
                        /* parse off argument, so we get right filename
                            in linker command file */
                        p = &Word[1];
                        if( Word[1] == '='  ||  Word[1] == '#' )
                            ++p;

                        /* remove quotes from object name */
                        UnquoteFName( unquoted, sizeof( unquoted ), p );

                        MemFree( Obj_Name );
                        Obj_Name = MemStrDup( unquoted );
                        break;
#if defined( WCLI86 ) || defined( WCL386 )
                    case 'p':           /* floating-point option */
                        end = p;
                        if( tolower( Word[1] ) == 'c' ) {
                            Flags.math_8087 = 0;
                        }
                        break;
#endif
                    default:
                        end = p;
                        break;
                    }
                    break;
                case 'k':               /* stack size option */
                    if( Word[0] != '\0' ) {
                        MemFree( StackSize );
                        StackSize = MemStrDup( Word );
                    }
                    wcc_option = 0;
                    break;
                case 'l':               /* link target option */
                    switch( (Word[1] << 8) | tolower( Word[0] ) ) {
                    case 'p':
                        Flags.link_for_dos = 0;
                        Flags.link_for_os2 = TRUE;
                        break;
                    case 'r':
                        Flags.link_for_dos = TRUE;
                        Flags.link_for_os2 = 0;
                        break;
                    default:                    /* 10-jun-91 */
                        Flags.link_for_sys = TRUE;
                        p = &Word[0];
                        if( Word[0] == '='  ||  Word[0] == '#' )
                            ++p;
                        MemFree( SystemName );
                        SystemName = MemStrDup( p );
                        break;
                    }
                    wcc_option = 0;
                    break;
                case 'x':
                    if( Word[0] == '\0' ) {
                        Flags.two_case = TRUE;
                        wcc_option = 0;
                    }
                    break;
                case '@':
                    if( Word[0] != '\0' ) {
                        char const * const      env = getenv( Word );

                        if( env != NULL ) {
                            if( handle_environment_variable( env ) ) {
                                return( 1 );          // Recursive call failed
                            }
                            via_environment = TRUE;
                            Cmd = end;
                            continue;
                        }

                        end = ScanFName( end, len );

                        /* remove quotes from additional linker options file */
                        UnquoteFName( unquoted, sizeof( unquoted ), Word );
                        strcpy( Word, unquoted );

                        MakeName( Word, ".lnk" );
                        errno = 0;
                        if( (atfp = fopen( Word, "r" )) == NULL ) {
                            PrintMsg( WclMsgs[UNABLE_TO_OPEN_DIRECTIVE_FILE], Word, strerror(  errno ) );
                            return( 1 );
                        }
                        while( fgets( buffer, sizeof( buffer ), atfp ) != NULL ) {
                            if( strnicmp( buffer, "file ", 5 ) == 0 ) {

                                /* look for names separated by ','s */
                                p = strchr( buffer, '\n' );
                                if( p != NULL )
                                    *p = '\0';
                                AddName( &buffer[5], Fp );
                                Flags.do_link = TRUE;
                            } else {
                                fputs( buffer, Fp );
                            }
                        }
                        fclose( atfp );
                    }
                    wcc_option = 0;
                    break;

                /* compiler options that affect the linker */
#ifdef WCL386
                case '3':
                case '4':
                case '5':                           /* 22-sep-92 */
                    Conventions = tolower( Word[0] );
                    break;
#endif
                case 'd':
                    if( DebugFlag == 0 ) {  /* not set by -h yet */
                        if( strcmp( Word, "1" ) == 0 ) {
                            DebugFlag = 1;
                        } else if( strcmp( Word, "1+" ) == 0 ) { /* 02-mar-91 */
                            DebugFlag = 2;
                        } else if( strcmp( Word, "2" ) == 0 ) {
                            DebugFlag = 2;
                        } else if( strcmp( Word, "2i" ) == 0 ) {
                            DebugFlag = 2;
                        } else if( strcmp( Word, "2s" ) == 0 ) {
                            DebugFlag = 2;
                        } else if( strcmp( Word, "3" ) == 0 ) {
                            DebugFlag = 2;
                        } else if( strcmp( Word, "3i" ) == 0 ) {
                            DebugFlag = 2;
                        } else if( strcmp( Word, "3s" ) == 0 ) {
                            DebugFlag = 2;
                        }
                    }
                    break;
                case 'h':
                    if( strcmp( Word, "w" ) == 0 ) {
                        DebugFlag = 3;
                    } else if( strcmp( Word, "c" ) == 0 ) { /* 02-mar-91 */
                        Flags.do_cvpack = 1;
                        DebugFlag = 4;
                    } else if( strcmp( Word, "d" ) == 0 ) {
                        DebugFlag = 5;
                    }
                    break;
                case 'i':           /* include file path */
                    end = ScanFName( end, len );
                    break;
                case 'c':           /* compile only */
                    if( stricmp( Word, "c" ) == 0 ) {
                        Flags.force_c = TRUE;
                    } else if( stricmp( Word, "c++" ) == 0 ) {
                        Flags.force_c_plus = TRUE;
                    } else {
                        Flags.no_link = TRUE;
                    }
                    wcc_option = 0;
                    break;
                case 'y':
                    if( stricmp( Word, "x" ) == 0 ) {
                        strcat( CC_Opts, " -x" );
                        wcc_option = 0;
                    } else if( Word[0] == '\0' ) {
                        wcc_option = 0;
                    }
                    break;
#if defined( WCLI86 ) || defined( WCL386 )
                case 'm':           /* memory model */
                    if( Cmd[1] == 't' || Cmd[1] == 'T' ) { /* tiny model*/
                        Word[0] = 's';              /* change to small */
                        Flags.tiny_model = TRUE;
                    }
                    break;
#endif
                case 'p':
                    Flags.no_link = TRUE;
                    break;      /* this is a preprocessor option */
                case 'q':
                    Flags.be_quiet = TRUE;
                    break;
                case 'z':                   /* 12-jan-89 */
                    switch( tolower( Cmd[1] ) ) {
                    case 's':
                        Flags.no_link = TRUE;
                        break;
                    case 'q':
                        Flags.be_quiet = TRUE;
                        break;
#ifdef WCLI86
                    case 'w':
                        Flags.windows = TRUE;
#endif
                    }
                    break;
                case '"':                           /* 17-dec-91 */
                    /* As parameter passing to linker is a special case, we need to pass
                     * whole command instead of first character removed. This allows us
                     * to parse also string literals in AddDirective.
                     */
                    wcc_option = 0;
                    strncpy( Word, Cmd, ++len );
                    Word[len] = '\0';
                    AddDirective( len );
                    break;
                }

                /* don't add linker-specific options */
                /* to compiler command line:     */

                if( wcc_option ) {
                    len = strlen( CC_Opts );
                    CC_Opts[len++] = ' ';
                    CC_Opts[len++] = opt;
                    CC_Opts[len++] = *Cmd;    /* keep original case */
                    CC_Opts[len] = '\0';
                    strcat( CC_Opts, Word );
                }
            }
            Cmd = end;
        }
    }

    return( 0 );
}
Exemple #16
0
EFI_STATUS EfiMain(EFI_HANDLE hImage, EFI_SYSTEM_TABLE *pST)
{
    EFI_LOADED_IMAGE *pImage;
    EFI_STATUS nStatus;
    EFI_HANDLE hDriver, *hBlkDevs;
    UINTN nBlkDevs;
    EFI_DEVICE_PATH *pBootPart, *pBootDisk = NULL;

    g_hImage = hImage;
    InitializeLib(hImage, pST);
    Print(L"%H\n*** UEFI:NTFS multiboot ***");

    if (EFI_ERROR((nStatus = BS->OpenProtocol(hImage, &LoadedImageProtocol, &pImage, hImage, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL)))) {
        Print(L"%E\nUnable to convert handle to interface: %r\n", nStatus);
        goto end;
    }

    pBootPart = DevicePathFromHandle(pImage->DeviceHandle);
    pBootDisk = GetParentDevice(pBootPart);

    CHAR16 *pszDev = DevicePathToStr(pBootDisk);
    Print(L"%N\nDisk: %s\n", pszDev);
    FreePool(pszDev);

    Print(L"%H\n[ INFO ] Disconnecting problematic File System drivers\n");
    DisconnectBlockingDrivers();

    Print(L"%H\n[ WAIT ] Loading NTFS driver");
    EFI_DEVICE_PATH *pDrvPath = FileDevicePath(pImage->DeviceHandle, DriverPath);
    if (pDrvPath == NULL) {
        Print(L"%E\r[ FAIL ] Unable to construct path to NTFS driver\n");
        goto end;
    }
    nStatus = BS->LoadImage(FALSE, hImage, pDrvPath, NULL, 0, &hDriver);
    FreePool(pDrvPath);
    if (EFI_ERROR(nStatus)) {
        Print(L"%E\r[ FAIL ] Unable to load NTFS driver: %r\n", nStatus);
        goto end;
    }
    if (EFI_ERROR((nStatus = BS->StartImage(hDriver, NULL, NULL)))) {
        Print(L"%E\r[ FAIL ] Unable to start NTFS driver: %r\n", nStatus);
        goto end;
    }

    Print(L"%H\r[  OK  ] NTFS driver loaded and started\n");

    LINKED_LOADER_PATH_LIST_NODE *list = NULL;
    EFI_DEVICE_PATH *ldr;

    if (EFI_ERROR((nStatus = BS->LocateHandleBuffer(ByProtocol, &BlockIoProtocol, NULL, &nBlkDevs, &hBlkDevs)))) {
        Print(L"%E\r[ FAIL ] Unable to enumerate block devices: %r\n", nStatus);
        goto end;
    }
    for (UINTN i = 0; i < nBlkDevs; i++) {
        EFI_DEVICE_PATH *pDevice = DevicePathFromHandle(hBlkDevs[i]);
        pszDev = DevicePathToStr(pDevice);
        Print(L"%N\r[ INFO ] Probing %d devices... [%d] %s", nBlkDevs, i + 1, pszDev);
        FreePool(pszDev);

        if (CompareDevicePaths(pDevice, pBootPart) == 0) continue;
        if (CompareDevicePaths(pDevice, pBootDisk) == 0) continue;

        EFI_DEVICE_PATH *pDisk = GetParentDevice(pDevice);
        _Bool probe = CompareDevicePaths(pDisk, pBootDisk) == 0;
        FreePool(pDisk);
#if !defined(_DEBUG)
        if (!probe) continue;
#endif

        EFI_BLOCK_IO *blkIo;
        if (EFI_ERROR((nStatus = BS->OpenProtocol(hBlkDevs[i], &BlockIoProtocol, &blkIo, hImage, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL)))) {
            Print(L"%E\n[ WARN ] Unable to open block device, skipping: %r\n", nStatus);
            continue;
        }

        //No media or not a partition.
        if ((blkIo->Media == NULL) || (!blkIo->Media->LogicalPartition))
            continue;

        CHAR8 *buffer = AllocatePool(blkIo->Media->BlockSize);
        if (buffer == NULL) {
            Print(L"%E\n[ WARN ] Unable to allocate buffer of size %d\n", blkIo->Media->BlockSize);
            continue;
        }

        nStatus = blkIo->ReadBlocks(blkIo, blkIo->Media->MediaId, 0, blkIo->Media->BlockSize, buffer);
        _Bool isNTFS = CompareMem(&buffer[3], NTFSMagic, sizeof(NTFSMagic)) == 0;
        FreePool(buffer);
        if (EFI_ERROR(nStatus)) {
            Print(L"%E\n[ WARN ] Unable to read block device, skipping: %r\n", nStatus);
            continue;
        }
        if (!isNTFS) continue;

        Print(L"%H\n[ WAIT ] Attaching NTFS driver to device");
        EFI_FILE_IO_INTERFACE *fs;
        nStatus = BS->OpenProtocol(hBlkDevs[i], &FileSystemProtocol, NULL, hImage, NULL, EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
        if (nStatus == EFI_UNSUPPORTED) {
            nStatus = BS->ConnectController(hBlkDevs[i], NULL, NULL, TRUE);
        }
        for (UINTN j = 0; j < NUM_RETRIES; j++) {
            if ((!EFI_ERROR((nStatus = BS->OpenProtocol(hBlkDevs[i], &FileSystemProtocol, &fs, hImage, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL))))) {
                break;
            }
            Print(L".");
            BS->Stall(DELAY * 1000000);
        }
        if(EFI_ERROR(nStatus)) {
            Print(L"%E\r[ WARN ] Unable to attach NTFS driver, skipping: %r\n", nStatus);
            continue;
        }
        Print(L"%H\r[  OK  ] NTFS driver attached to current device\n");

        Print(L"%H\r[ WAIT ] Locating EFI boot loader");
        EFI_FILE *fsRoot;
        if (EFI_ERROR((nStatus = fs->OpenVolume(fs, &fsRoot)))) {
            Print(L"%E\r[ WARN ] Unable to open root directory, skipping: %r\n", nStatus);
            continue;
        }
        CHAR16 *loader = StrDuplicate(LoaderPath);
        if (EFI_ERROR((nStatus = SetPathCase(fsRoot, loader)))) {
            FreePool(loader);
            Print(L"%E\r[ WARN ] Unable to locate EFI boot loader on this device: %r\n", nStatus);
            continue;
        }
        Print(L"%H\r[  OK  ] EFI boot loader located at %s\n", loader);

        ldr = FileDevicePath(hBlkDevs[i], loader);
        ListAppend(&list, ldr);
        FreePool(loader);
    }

    UINTN nListEntries = 0, nBootEntry = 0, nPage = 0, nTotalPage = 0;
    EFI_INPUT_KEY key;
    _Bool interactive = FALSE;
    ListTraverse(&list, CountEntries, 0, 0, &nListEntries);

    switch (nListEntries) {
    case 0:
        Print(L"%E\n[ FAIL ] No bootable partition\n", nStatus);
        nStatus = EFI_NOT_FOUND;
        goto end;
    case 1:
        goto boot;
    default:
        nTotalPage = (nListEntries - 1) / PAGE_SIZE + 1;
        while (1) {
            ST->ConOut->ClearScreen(ST->ConOut);
            Print(L"%H*** UEFI:NTFS Multiboot ***\n");
            pszDev = DevicePathToStr(pBootDisk);
            Print(L"%NDisk: %s\n\n%H", pszDev);
            FreePool(pszDev);

            ListTraverse(&list, DisplayEntries, nPage * PAGE_SIZE, PAGE_SIZE, NULL);

            Print(L"%N\nPage %hd / %hd, %hd entries\n", nPage + 1, nTotalPage, nListEntries);
            Print(L"%H\n[F1 - F8] [1 - 8] %N Boot corresponding entry");
            Print(L"%H\n[PgUp]  [<]  [-]  %N Previous page");
            Print(L"%H\n[PgDn]  [>]  [+]  %N Next page");

            if (!interactive) {
                INTN nCountDown = AUTOBOOT_TIME;
                Print(L"%N\n\n");
                while (nCountDown >= 0) {
                    Print(L"\rWill automatically boot the first entry in %d seconds...", nCountDown);
                    if (WaitForSingleEvent(ST->ConIn->WaitForKey, 1000 * 1000 * 10) != EFI_TIMEOUT) {
                        interactive = TRUE;
                        break;
                    }
                    nCountDown--;
                }
                if (!interactive) {
                    goto boot;
                }
            }
            else {
                WaitForSingleEvent(ST->ConIn->WaitForKey, 0);
            }
            ST->ConIn->ReadKeyStroke(ST->ConIn, &key);
            switch (key.UnicodeChar) {
            case L'1':case L'2':case L'3':case L'4':case L'5':case L'6':case L'7':case L'8':
                nBootEntry = nPage * PAGE_SIZE + (key.UnicodeChar - L'1');
                goto boot;
            case L'+':case L'=':case L'>':case L'.':
                if ((nPage + 1) != nTotalPage) {
                    nPage++;
                }
                break;
            case L'-':case L'_': case L'<': case L',':
                if (nPage != 0) {
                    nPage--;
                }
                break;
            default:
                switch (key.ScanCode) {
                case 0x09:
                    if (nPage != 0) {
                        nPage--;
                    }
                    break;
                case 0x0a:
                    if ((nPage + 1) != nTotalPage) {
                        nPage++;
                    }
                    break;
                case 0x0b:case 0x0c:case 0x0d:case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12:
                    nBootEntry = nPage * PAGE_SIZE + (key.ScanCode - 0x0b);
                    goto boot;
                }
            }
        }
    }

boot:
    ldr = NULL;
    Print(L"%H");
    ST->ConOut->ClearScreen(ST->ConOut);
    ListTraverse(&list, ReadEntry, nBootEntry, 1, &ldr);
    ListTraverse(&list, DisplayEntries, nBootEntry, 1, NULL);
    if (ldr == NULL) {
        Print(L"%E\n[ FAIL ] No such boot entry\n", nStatus);
        nStatus = EFI_NOT_FOUND;
        goto end;
    }

    ldr = DuplicateDevicePath(ldr);
    ListTraverse(&list, DestroyEntries, 0, 0, NULL);
    ListDestroy(&list);

    EFI_HANDLE hChain;
    nStatus = BS->LoadImage(FALSE, hImage, ldr, NULL, 0, &hChain);
    FreePool(ldr);
    if (EFI_ERROR(nStatus)) {
        Print(L"%E\n[ FAIL ] Unable to load boot loader: %r\n", nStatus);
        goto end;
    }
    Print(L"%N");
    if (EFI_ERROR((nStatus = BS->StartImage(hChain, NULL, NULL)))) {
        Print(L"%E\n[ FAIL ] Unable to start boot loader: %r\n", nStatus);
        goto end;
    }

end:
    if (pBootDisk) FreePool(pBootDisk);
    if (EFI_ERROR(nStatus)) {
        Print(L"Press any key to exit\n");
        WaitForSingleEvent(ST->ConIn->WaitForKey, 0);
        ST->ConIn->ReadKeyStroke(ST->ConIn, &key);
    }
    return nStatus;
}
Exemple #17
0
static  int  ParseArgs( int argc, char **argv )
/*********************************************/
{
    char        *p;
    int         wcc_option;
    int         c;
    int         i;
    list        *new_item;

    initialize_Flags();
    DebugFlag          = 1;
    StackSize = NULL;
    Conventions[0]     = 'r';
    Conventions[1]     = '\0';
    preprocess_only    = 0;
    cpp_want_lines     = 1; /* NB: wcc and wcl default to 0 here */
    cpp_keep_comments  = 0;
    cpp_encrypt_names  = 0;
    cpp_linewrap       = NULL;
    O_Name             = NULL;

    AltOptChar = '-'; /* Suppress '/' as option herald */
    while( (c = GetOpt( &argc, argv,
#if 0
                        "b:Cc::D:Ef:g::"
                        "HI:i::k:L:l:M::m:"
                        "O::o:P::QSs::U:vW::wx:yz::",
#else
                        "b:CcD:Ef:g::"
                        "HI:i::k:L:l:M::m:"
                        "O::o:P::QSs::U:vW::wx::yz::",
#endif
                        EnglishHelp )) != -1 ) {

        char    *Word = "";
        int     found_mapping = FALSE;

        for( i = 0; i < sizeof( mappings ) / sizeof( mappings[0] ); i++ ) {
            option_mapping  *m    = mappings + i;
            char            *tail = strchr( m->LongName, ':' );

            if( c != m->LongName[0] )
                continue;
            if( OptArg == NULL ) {
                if( m->LongName[1] == '\0' ) {
                    strcat( CC_Opts, " -" );
                    strcat( CC_Opts, m->WatcomName );
                    found_mapping = TRUE;
                    break;
                }
                /* non-existant argument can't match other cases */
                continue;
            }
            if( tail != NULL ) {
                if( !strncmp( OptArg, m->LongName + 1,
                              tail - m->LongName - 1 ) ) {
                    strcat( CC_Opts, " -" );
                    strcat( CC_Opts, m->WatcomName );
                    strcat( CC_Opts, OptArg + ( tail - m->LongName - 1) );
                    found_mapping = TRUE;
                    break;
                }
            } else if( !strcmp( OptArg, m->LongName + 1 ) ) {
                strcat( CC_Opts, " -" );
                strcat( CC_Opts, m->WatcomName );
                found_mapping = TRUE;
                break;
            }
        }
        if( found_mapping )
            continue;

        if( OptArg != NULL ) {
            Word = MemAlloc( strlen( OptArg ) + 6 );
            strcpy( Word, OptArg );
        }

        wcc_option = 1;

        switch( c ) {
        case 'f':
            if( !strcmp( Word, "syntax-only" ) ) {
                c = 'z';
                strcpy( Word, "s" );
                Flags.no_link = 1;
                break;
            }
            if( !strncmp( Word, "cpp-wrap=", 9 ) ) {
                MemFree( cpp_linewrap );
                Word[7] = 'w';
                cpp_linewrap = MemStrDup( Word + 7 );
                wcc_option = 0;
                break;
            }
            if( !strcmp( Word, "mangle-cpp" ) ) {
                cpp_encrypt_names = 1;
                wcc_option = 0;
                break;
            }
            switch( Word[0] ) {
            case 'd':           /* name of linker directive file */
                if( Word[1] == '='  ||  Word[1] == '#' ) {
                    MakeName( Word, ".lnk" );    /* add extension */
                    MemFree( Link_Name );
                    Link_Name = strfdup( Word + 2 );
                } else {
                    MemFree( Link_Name );
                    Link_Name = MemStrDup( TEMPFILE );
                }
                wcc_option = 0;
                break;
            case 'm':           /* name of map file */
                Flags.map_wanted = TRUE;
                if( Word[1] == '='  ||  Word[1] == '#' ) {
                    MemFree( Map_Name );
                    Map_Name = strfdup( Word + 2 );
                }
                wcc_option = 0;
                break;
            case 'o':           /* name of object file */
                /* parse off argument, so we get right filename
                   in linker command file */
                p = &Word[1];
                if( Word[1] == '='  ||  Word[1] == '#' ) {
                    ++p;
                }
                MemFree( Obj_Name );
                Obj_Name = strfdup( p );        /* 08-mar-90 */
                break;
            case 'r':           /* name of error report file */
                Flags.want_errfile = TRUE;
                break;
            }
            /* avoid passing on unknown options */
            wcc_option = 0;
            break;

        case 'k':               /* stack size option */
            if( Word[0] != '\0' ) {
                MemFree( StackSize );
                StackSize = MemStrDup( Word );
            }
            wcc_option = 0;
            break;

        /* compiler options that affect the linker */
        case 'c':           /* compile only */
            Flags.no_link = TRUE;
            wcc_option = 0;
            break;
        case 'x':           /* change source language */
            if( strcmp( Word, "c" ) == 0 ) {
                Flags.force_c = TRUE;
            } else if( strcmp( Word, "c++" ) == 0 ) {
                Flags.force_c_plus = TRUE;
            } else {
                Flags.no_link = TRUE;
            }
            wcc_option = 0;
            break;

        case 'm':
            if( ( !strncmp( "cmodel=", Word, 7 ) )
                && ( Word[8] == '\0' ) ) {
                if( Word[7] == 't' ) {      /* tiny model */
                    Word[0] = 's';              /* change to small */
                    Flags.tiny_model = TRUE;
                } else {
                    Word[0] = Word[7];
                }
                Word[1] = '\0';
                break;
            }
            if( !strncmp( "regparm=", Word, 8 ) ) {
                if( !strcmp( Word + 8, "0" ) ) {
                    Conventions[0] =  's';
                } else {
                    Conventions[0] = 'r';
                }
                wcc_option = 0;
                break;
            }
            if( !strncmp( "tune=i", Word, 6 ) ) {
                switch( Word[6] ) {
                case '0':
                case '1':
                case '2':
                    CPU_Class = Word[6];
                    Conventions[0] = '\0';
                    break;
                case '3':
                case '4':
                case '5':
                case '6':
                    CPU_Class = Word[6];
                    break;
                default:
                    /* Unknown CPU type --- disable generation of this
                     * option */
                    CPU_Class = '\0';
                }
                wcc_option = 0;
                break;
            }
            wcc_option = 0;     /* dont' pass on unknown options */
            break;

        case 'z':                   /* 12-jan-89 */
            switch( tolower( Word[0] ) ) {
            case 's':
                Flags.no_link = TRUE;
                break;
            case 'q':
                Flags.be_quiet = TRUE;
                break;
            case 'w':
                Flags.windows = TRUE;
            }
            break;
        case 'E':
            preprocess_only = 1;
            wcc_option = 0;
            break;
        case 'P':
            cpp_want_lines = 0;
            wcc_option = 0;
            break;
        case 'C':
            cpp_keep_comments = 1;
            wcc_option = 0;
            break;
        case 'o':
            MemFree( O_Name );
            O_Name = strfdup( OptArg );
            wcc_option = 0;
            break;
        case 'g':
            if( OptArg == NULL ) {
                Word = "2";
            } else if( !isdigit( OptArg[0] ) ) {
                c = 'h';
                if( strcmp( Word, "w" ) == 0 ) {
                    DebugFlag = 3;
                } else if( strcmp( Word, "c" ) == 0 ) { /* 02-mar-91 */
                    Flags.do_cvpack = 1;
                    DebugFlag = 4;
                } else if( strcmp( Word, "d" ) == 0 ) {
                    DebugFlag = 5;
                }
                break;
            }
            c = 'd';
        parse_d:
            if( DebugFlag == 0 ) {  /* not set by -h yet */
                if( strcmp( Word, "1" ) == 0 ) {
                    DebugFlag = 1;
                } else if( strcmp( Word, "1+" ) == 0 ) { /* 02-mar-91 */
                    DebugFlag = 2;
                } else if( strcmp( Word, "2" ) == 0 ) {
                    DebugFlag = 2;
                } else if( strcmp( Word, "2i" ) == 0 ) {
                    DebugFlag = 2;
                } else if( strcmp( Word, "2s" ) == 0 ) {
                    DebugFlag = 2;
                } else if( strcmp( Word, "3" ) == 0 ) {
                    DebugFlag = 2;
                } else if( strcmp( Word, "3i" ) == 0 ) {
                    DebugFlag = 2;
                } else if( strcmp( Word, "3s" ) == 0 ) {
                    DebugFlag = 2;
                }
            }
            break;
        case 'S':
            Flags.do_disas = TRUE;
            Flags.no_link = TRUE;
            if( DebugFlag == 0 ) {
                c = 'd';
                Word = "1";
                goto parse_d;
            }
            wcc_option = 0;
            break;
        case 's':
            if( OptArg != NULL ) {
                /* leave -shared to mapping table */
                wcc_option = 0;
                break;
            }
            Flags.strip_all = 1;
            DebugFlag = 0;
            wcc_option = 0;
            break;
        case 'v':
            Flags.be_quiet = 0;
            wcc_option = 0;
            break;
        case 'W':
            if( OptArg != NULL && strncmp( OptArg, "l,", 2 ) == 0 ) {
                AddDirective( OptArg + 2 );
                wcc_option = 0;
            }
            /* other cases handled by table */
            break;
        case 'I':
            xlate_fname( Word );
            break;
        case 'b':
            Flags.link_for_sys = TRUE;
            MemFree( SystemName );
            SystemName = MemStrDup( Word );
            /* if Word found in specs.owc, add options from there: */
            if( ConsultSpecsFile( Word ) ) {
                /* all set */
                wcc_option = 0;
            } else {
                /* not found --- default to bt=<system> */
                strcpy( Word, "t=" );
                strcat( Word, SystemName );
            }
            break;
        case 'l':
            new_item = MemAlloc( sizeof( list ) );
            new_item->next = NULL;
            p = MemAlloc( strlen( OptArg ) + 2 + 1 );
            strcpy( p, OptArg );
            strcat( p, ".a" );
            new_item->item = strfdup( p );
            MemFree( p );
            ListAppend( &Libs_List, new_item );
            wcc_option = 0;
            break;
        case 'L':
            xlate_fname( Word );
            fputs( "libpath ", Fp );
            Fputnl( Word, Fp );
            wcc_option = 0;
            break;
        case 'i':       /* -include <file> --> -fi=<file> */
            if( OptArg == NULL ) {
                wcc_option = 0;
                break;
            }
            if( !strcmp( OptArg, "nclude" ) ) {
                c = 'f';
                Word = MemReAlloc( Word, strlen( argv[OptInd] ) + 6 );
                if( OptInd >= argc - 1 ) {
                    MemFree( cpp_linewrap );
                    PrintMsg( "Argument of -include missing\n", OptArg );
                    return( 1 );
                }
                strcpy( Word, "i=" );
                strfcat( Word, argv[OptInd] );
                argv[OptInd++][0] = '\0';
                break;
            }
            /* avoid passing un unknown options */
            wcc_option = 0;
            break;

        case 'M':               /* autodepend information for Unix makes */
            if( OptArg == NULL ) {
                wcc_option = 0;
                break;
            }
            c = 'a';
            if( !strcmp( OptArg, "D" ) ||
                !strcmp( OptArg, "MD" ) ) {
                /* NB: only -MMD really matches OW's behaviour, but
                 * for now, let's accept -MD to mean the same */
                /* translate to -adt=.o */
                strcpy( Word, "dt=.o" );
            } else if( !strcmp( OptArg, "F" ) ) {
                Word = MemReAlloc( Word, strlen( argv[OptInd] ) + 6 );
                if( OptInd >= argc - 1 ) {
                    MemFree( cpp_linewrap );
                    PrintMsg( "Argument of -MF missing\n", OptArg );
                    return( 1 );
                }
                strcpy( Word, "d=" );
                strfcat( Word, argv[OptInd] );
                argv[OptInd++][0] = '\0';
            } else if( !strcmp( OptArg, "T") ) {
                Word = MemReAlloc( Word, strlen( argv[OptInd] ) + 6 );
                if( OptInd >= argc - 1 ) {
                    MemFree( cpp_linewrap );
                    PrintMsg( "Argument of -M%s missing\n", OptArg );
                    return( 1 );
                }
                strcpy( Word, "dt=" );
                strcat( Word, argv[OptInd] );
                argv[OptInd++][0] = '\0';
            } else {
                /* avoid passing on incompatible options */
                wcc_option = 0;
            }
            break;
        }

        /* don't add linker-specific options */
        /* to compiler command line:     */
        if( wcc_option ) {
            addccopt( c, Word );
        }
        if( OptArg != NULL ) {
            MemFree( Word );
            Word = NULL;
        }
    }

    if( preprocess_only ) {
        Flags.no_link = TRUE;
        if( O_Name == NULL ) {
            MemFree( Obj_Name );           /* preprocess to stdout by default */
            Obj_Name = NULL;
        }
        strcat( CC_Opts, " -p" );
        if( cpp_encrypt_names )
            strcat( CC_Opts, "e" );
        if( cpp_want_lines )
            strcat( CC_Opts, "l" );
        if( cpp_keep_comments )
            strcat( CC_Opts, "c" );
        if( cpp_linewrap != NULL ) {
            strcat( CC_Opts, cpp_linewrap );
        }
    }
    if( CPU_Class )
        addccopt( CPU_Class, Conventions );
    if( Flags.be_quiet )
        addccopt( 'z', "q" );
    if( O_Name != NULL ) {
        if( Flags.no_link && !Flags.do_disas ) {
            MemFree( Obj_Name );
            Obj_Name = O_Name;
        } else {
            strcpy( Exe_Name, O_Name );
            Flags.keep_exename = 1;
            MemFree( O_Name );
        }
        O_Name = NULL;
    }
    if( Obj_Name != NULL ) {
        strcat( CC_Opts, " -fo=" );
        strcat( CC_Opts, Obj_Name );
    }
    if( !Flags.want_errfile ) {
        strcat( CC_Opts, " -fr" );
    }
    for( i = 1; i < argc ; i++ ) {
        Word = argv[i];
        if( Word == NULL || Word[0] == '\0' )
            /* HBB 20060217: argument was used up */
            continue;
        new_item = MemAlloc( sizeof( list ) );
        new_item->next = NULL;
        new_item->item = strfdup( Word );
        if( FileExtension( Word, ".lib" ) || FileExtension( Word, ".a" ) ) {
            ListAppend( &Libs_List, new_item );
        } else {
            ListAppend( &Files_List, new_item );
        }
    }
    MemFree( cpp_linewrap );
    return( 0 );
}
Exemple #18
0
/**
 * Process an incoming publish packet for a socket
 * @param pack pointer to the publish packet
 * @param sock the socket on which the packet was received
 * @return completion code
 */
int MQTTProtocol_handlePublishes(void* pack, int sock)
{
	Publish* publish = (Publish*)pack;
	Clients* client = NULL;
	char* clientid = NULL;
	int rc = TCPSOCKET_COMPLETE;
#if !defined(SINGLE_LISTENER)
	Listener* listener = Socket_getParentListener(sock);
#endif

	FUNC_ENTRY;
	if (sock == 0)
	  clientid = INTERNAL_CLIENTID; /* this is an internal client */
	else
	{
		client = (Clients*)(ListFindItem(bstate->clients, &sock, clientSocketCompare)->content);
		clientid = client->clientID;
		Log(LOG_PROTOCOL, 11, NULL, sock, clientid, publish->msgId, publish->header.bits.qos,
				publish->header.bits.retain, min(20, publish->payloadlen), publish->payload);
		if (Protocol_isClientQuiescing(client))
			goto exit; /* don't accept new work */
#if !defined(SINGLE_LISTENER)
		if (listener && listener->mount_point)
		{
			char* temp = malloc(strlen(publish->topic) + strlen(listener->mount_point) + 1);
			strcpy(temp, listener->mount_point);
			strcat(temp, publish->topic);
			free(publish->topic);
			publish->topic = temp;
		}
#endif
	}

#if !defined(NO_BRIDGE)
	if (client && client->outbound)
		Bridge_handleInbound(client, publish);
#endif

	if (publish->header.bits.qos == 0)
	{
		if (strlen(publish->topic) < 5 || strncmp(publish->topic, sysprefix, strlen(sysprefix)) != 0)
		{
			++(bstate->msgs_received);
			bstate->bytes_received += publish->payloadlen;
		}
		Protocol_processPublication(publish, clientid);
	}
	else if (publish->header.bits.qos == 1)
	{
		/* send puback before processing the publications because a lot of return publications could fill up the socket buffer */
		rc = MQTTPacket_send_puback(publish->msgId, sock, clientid);
		/* if we get a socket error from sending the puback, should we ignore the publication? */
		Protocol_processPublication(publish, clientid);
		++(bstate->msgs_received);
		bstate->bytes_received += publish->payloadlen;
	}
	else if (publish->header.bits.qos == 2)
	{
		/* store publication in inbound list */
		int len;
		ListElement* listElem = NULL;
		Messages* m = NULL;
		Publications* p = NULL;

		/*if list is full, disconnect the client with warning message */
		if (client->inboundMsgs->count >= (bstate->max_inflight_messages*2))
		{
			Log(LOG_WARNING, 69, NULL, clientid);
			rc = SOCKET_ERROR; /* will cause the client to be disconnected */
			goto exit;
		}

		p = MQTTProtocol_storePublication(publish, &len);
		if ((listElem = ListFindItem(client->inboundMsgs, &publish->msgId, messageIDCompare)) != NULL)
		{
			m = (Messages*)(listElem->content);
			MQTTProtocol_removePublication(m->publish); /* remove old publication data - could be different */
		}
		else
			m = malloc(sizeof(Messages));

		m->publish = p;
		m->msgid = publish->msgId;
		m->qos = publish->header.bits.qos;
		m->priority = publish->priority;
		m->retain = publish->header.bits.retain;
		m->nextMessageType = PUBREL;

		if (listElem == NULL)
			ListAppend(client->inboundMsgs, m, sizeof(Messages) + len);
		rc = MQTTPacket_send_pubrec(publish->msgId, sock, clientid);
	}
exit:
	if (sock < -1 || sock > 0)
		MQTTPacket_freePublish(publish);
	FUNC_EXIT_RC(rc);
	return rc;
}
Exemple #19
0
int Protocol_handlePublishes(Publish* publish, int sock, Clients* client, char* clientid)
#endif
{
	int rc = TCPSOCKET_COMPLETE;
#if !defined(SINGLE_LISTENER)
	Listener* listener = NULL;
#endif

	FUNC_ENTRY;
	if (Protocol_isClientQuiescing(client))
		goto exit; /* don't accept new work */
#if !defined(SINGLE_LISTENER)
	listener = Socket_getParentListener(sock);
	if (listener && listener->mount_point)
	{
		char* temp = malloc(strlen(publish->topic) + strlen(listener->mount_point) + 1);
		strcpy(temp, listener->mount_point);
		strcat(temp, publish->topic);
		free(publish->topic);
		publish->topic = temp;
	}
#endif

#if !defined(NO_BRIDGE)
	if (client && client->outbound)
		Bridge_handleInbound(client, publish);
#endif

	if (publish->header.bits.qos == 0)
	{
		if (strlen(publish->topic) < 5 || strncmp(publish->topic, sysprefix, strlen(sysprefix)) != 0)
		{
			++(bstate->msgs_received);
			bstate->bytes_received += publish->payloadlen;
		}
		Protocol_processPublication(publish, clientid);
	}
	else if (publish->header.bits.qos == 1)
	{
		/* send puback before processing the publications because a lot of return publications could fill up the socket buffer */
#if defined(MQTTS)
		if (client->protocol == PROTOCOL_MQTTS)
			rc = MQTTSPacket_send_puback(client, topicId, publish->msgId, MQTTS_RC_ACCEPTED);
		else
#endif
			rc = MQTTPacket_send_puback(publish->msgId, sock, clientid);
		/* if we get a socket error from sending the puback, should we ignore the publication? */
		Protocol_processPublication(publish, clientid);
		++(bstate->msgs_received);
		bstate->bytes_received += publish->payloadlen;
	}
	else if (publish->header.bits.qos == 2 && client->inboundMsgs->count < bstate->max_inflight_messages)
	{
		/* store publication in inbound list - if list is full, ignore and rely on client retry */
		int len;
		ListElement* listElem = NULL;
		Messages* m = NULL;
		Publications* p = MQTTProtocol_storePublication(publish, &len);

		if ((listElem = ListFindItem(client->inboundMsgs, &publish->msgId, messageIDCompare)) != NULL)
		{
			m = (Messages*)(listElem->content);
			MQTTProtocol_removePublication(m->publish); /* remove old publication data - could be different */
		}
		else
			m = malloc(sizeof(Messages));

		m->publish = p;
		m->msgid = publish->msgId;
		m->qos = publish->header.bits.qos;
		m->retain = publish->header.bits.retain;
		m->nextMessageType = PUBREL;

		if (listElem == NULL)
			ListAppend(client->inboundMsgs, m, sizeof(Messages) + len);
#if defined(MQTTS)
		if (client->protocol == PROTOCOL_MQTTS)
			rc = MQTTSPacket_send_pubrec(client, publish->msgId);
		else
#endif
			rc = MQTTPacket_send_pubrec(publish->msgId, sock, clientid);
	}
	else if (publish->header.bits.qos == 3) /* only applies to MQTT-S */
	{
		publish->header.bits.qos = 0;
		Protocol_processPublication(publish, clientid);
	}
exit:
	if (sock > 0)
		MQTTPacket_freePublish(publish);
	FUNC_EXIT_RC(rc);
	return rc;
}
Exemple #20
0
EXPR *FindBasic( EXPR *def )
    {
    unsigned int i ;
    EXPR *expr, *E1, *E2 ;

    if( IsReal(def) )
	{
	expr = new UNIT ;
  	U(expr)->Ehead = String( "Ordinate" ) ;
	ListAppend( expr, def->Copy() ) ;
	return expr ;
	}

    if( IsLabel( def ) )
	{
	for( i = 0 ; i < U(UnitList)->used ; i++ )
	    {
	    if( U(UN(i))->Ehead == def )
		{
		expr = UN(i)->Copy() ;
		delete U(expr)->Eeval ;
		U(expr)->Eeval = NULL_EXPR ;
		return expr ;
		}
	    }
	IOerror( IO_ERR, "FindBasic", "%s is an undefined unit", LabelValue(def) ) ;
	return garbageunit() ;
	}

    if( !IsOper(def) )
	{
	IOerror( IO_FATAL, "FindBasic", "unexpected in units definition" ) ;
	return garbageunit() ;
	}

    if( D(def)->oper == OPER_MINUS )
	{
	expr = FindBasic( D(def)->Eleft ) ;
	if( U(expr)->used > 1 )
	    {
	    IOerror( IO_ERR, "FindBasic", "illegal negation of unit" ) ;
	    return garbageunit() ;
	    }
	E1 = OP3( "u-", U(expr)->list[0], NULL_EXPR ) ;
	delete U(expr)->list[0] ;
	U(expr)->list[0] = E1 ;
	return expr ;
	}

    E1 = FindBasic( D(def)->Eleft ) ;
    E2 = FindBasic( D(def)->Eright ) ;

    switch( D(def)->oper )
	{
	case OPER_MULTIPLY:

	    expr = UnitOP3( "*", "+", E1, E2 ) ;
	    break ;
	case OPER_DIVIDE:
	    expr = UnitOP3( "/", "-", E1, E2 ) ;
	    break ;
	case OPER_POW:
	    expr = UnitOP3( "^", "*", E1, E2 ) ;
	    break ;
	default:
	    IOerror( IO_ERR, "FindBasic", "unexpected operator in unit" ) ;
	    expr = garbageunit() ;
	    break ;
	    }

    delete E1 ;
    delete E2 ;
    return expr ;
    }
uint8_t fhssDistributedBlacklistMABFirstBestArmChan(Node_t *parent, Node_t *child, uint64_t asn)
{
    uint8_t freq = 0;

    /* Every epsilon_ts_incr_n time slots we divide increment epsilon_n */
    if ((epsilon_ts_incr_n != 0) && ((asn + 1) % epsilon_ts_incr_n) == 0)
    {
        if (++epsilon_n == epsilon_max_n) {
            epsilon_n = epsilon_init_n;
            PRINTF("Reseting Epsilon to %ld at %lld\n", (long)epsilon_init_n, (long long)asn);
        }
    }

    if ((rand() % epsilon_n) == 0)
    {
        /* We will explore all channels randomly */

        return (fhssDistributedBlacklistMABExplore(parent, asn));
    }
    else
    {
        /* Lets order all channel sorting by average_reward */
        List ordered_channel; memset(&ordered_channel, 0, sizeof(List)); ListInit(&ordered_channel);
        for (uint8_t i = 0; i < NUM_CHANNELS; i++)
        {
            ListElem *elem;
            for (elem = ListFirst(&ordered_channel); elem != NULL; elem = ListNext(&ordered_channel, elem))
            {
                uint8_t channel = (uint8_t)elem->obj;

                if (parent->avg_reward[child->id][i] > parent->avg_reward[child->id][channel])
                {
                    ListInsertBefore(&ordered_channel, (void *)i, elem);
                    break;
                }
            }

            if (elem == NULL)
            {
                ListAppend(&ordered_channel, (void *)i);
            }
        }

        /* Create a blacklist with the first best MAB_FIRST_BEST_ARMS channels */
        uint16_t blacklist = 0;
        uint8_t n_channels = 1;
        for (ListElem *elem = ListFirst(&ordered_channel); elem != NULL; elem = ListNext(&ordered_channel, elem))
        {
            uint8_t channel = (uint8_t)elem->obj;
            blacklist |= (1 << channel);

            /* Check if we already got the MAB_FIRST_BEST_ARMS first best channels */
            if (++n_channels > mab_first_best_arms)
            {
                break;
            }
        }

        for (ListElem *elem = ListFirst(&parent->channels); elem != NULL; elem = ListNext(&parent->channels, elem))
        {
            uint8_t freq_off = (uint8_t)elem->obj;

            freq = fhssOpenwsnChan(freq_off, asn);
            if (blacklist & (1 << freq))
            {
                return (freq);
            }
        }

        return (freq);
    }
    return 0;
}
Exemple #22
0
/**
 * Restores the persisted records to the outbound and inbound message queues of the
 * client.
 * @param client the client as ::Clients.
 * @return 0 if success, #MQTTCLIENT_PERSISTENCE_ERROR otherwise.
 */
int MQTTPersistence_restore(Clients *c)
{
	int rc = 0;
	char **msgkeys = NULL,
		 *buffer = NULL;
	int nkeys, buflen;
	int i = 0;
	int msgs_sent = 0;
	int msgs_rcvd = 0;

	FUNC_ENTRY;
	if (c->persistence && (rc = c->persistence->pkeys(c->phandle, &msgkeys, &nkeys)) == 0)
	{
		while (rc == 0 && i < nkeys)
		{
			if (strncmp(msgkeys[i], PERSISTENCE_COMMAND_KEY, strlen(PERSISTENCE_COMMAND_KEY)) == 0)
				;
			else if (strncmp(msgkeys[i], PERSISTENCE_QUEUE_KEY, strlen(PERSISTENCE_QUEUE_KEY)) == 0)
				;
			else if ((rc = c->persistence->pget(c->phandle, msgkeys[i], &buffer, &buflen)) == 0)
			{
				MQTTPacket* pack = MQTTPersistence_restorePacket(buffer, buflen);
				if ( pack != NULL )
				{
					if ( strstr(msgkeys[i],PERSISTENCE_PUBLISH_RECEIVED) != NULL )
					{
						Publish* publish = (Publish*)pack;
						Messages* msg = NULL;
						msg = MQTTProtocol_createMessage(publish, &msg, publish->header.bits.qos, publish->header.bits.retain);
						msg->nextMessageType = PUBREL;
						/* order does not matter for persisted received messages */
						ListAppend(c->inboundMsgs, msg, msg->len);
						publish->topic = NULL;
						MQTTPacket_freePublish(publish);
						msgs_rcvd++;
					}
					else if ( strstr(msgkeys[i],PERSISTENCE_PUBLISH_SENT) != NULL )
					{
						Publish* publish = (Publish*)pack;
						Messages* msg = NULL;
						char *key = malloc(MESSAGE_FILENAME_LENGTH + 1);
						sprintf(key, "%s%d", PERSISTENCE_PUBREL, publish->msgId);
						msg = MQTTProtocol_createMessage(publish, &msg, publish->header.bits.qos, publish->header.bits.retain);
						if ( c->persistence->pcontainskey(c->phandle, key) == 0 )
							/* PUBLISH Qo2 and PUBREL sent */
							msg->nextMessageType = PUBCOMP;
						/* else: PUBLISH QoS1, or PUBLISH QoS2 and PUBREL not sent */
						/* retry at the first opportunity */
						msg->lastTouch = 0;
						MQTTPersistence_insertInOrder(c->outboundMsgs, msg, msg->len);
						publish->topic = NULL;
						MQTTPacket_freePublish(publish);
						free(key);
						msgs_sent++;
					}
					else if ( strstr(msgkeys[i],PERSISTENCE_PUBREL) != NULL )
					{
						/* orphaned PUBRELs ? */
						Pubrel* pubrel = (Pubrel*)pack;
						char *key = malloc(MESSAGE_FILENAME_LENGTH + 1);
						sprintf(key, "%s%d", PERSISTENCE_PUBLISH_SENT, pubrel->msgId);
						if ( c->persistence->pcontainskey(c->phandle, key) != 0 )
							rc = c->persistence->premove(c->phandle, msgkeys[i]);
						free(pubrel);
						free(key);
					}
				}
				else  /* pack == NULL -> bad persisted record */
					rc = c->persistence->premove(c->phandle, msgkeys[i]);
			}
			if (buffer)
			{
				free(buffer);
				buffer = NULL;
			}
			if (msgkeys[i])
				free(msgkeys[i]);
			i++;
		}
		if (msgkeys)
			free(msgkeys);
	}
	Log(TRACE_MINIMUM, -1, "%d sent messages and %d received messages restored for client %s\n", 
		msgs_sent, msgs_rcvd, c->clientID);
	MQTTPersistence_wrapMsgID(c);

	FUNC_EXIT_RC(rc);
	return rc;
}