Ejemplo n.º 1
0
//Send event from repeater to outside world by forking an event-sending process
//If event-sending process is running, check if it finished and clean up
void handleRepeaterEvents(void)
{
    pid_t pid;
    
    if (0 == eventProc) {
        //Event posting process is not running, create one if events in fifo
        if (!isFifoEmpty()) {
            //fork doEvent
            pid = fork();
            if (-1 == pid) {
                //fork failed. This is so unfair. Exit and blame Linus ;-)
                fatal(LEVEL_0, "handleRepeaterEvents(): fork() failed. Linus, this is *so* unfair\n");
            }
            else if (0 == pid) {
                //child code
                debug(LEVEL_3, "handleRepeaterEvents(): in child process, starting doEventWork()\n");
                exit(doEventWork());
            }
            else {
                //parent code
                //Store child pid to variable eventProc so we can
                //properly clean up after child has exited
                eventProc = pid;
                
                //Clean parent process' fifo
                clearFifo();
            }
        }
    }
    else {
        //Event-sending process is running, check if run has ended
        cleanUpAfterEventProc();
    }
}
// ************************ USB interrupt event processing *************************
void usbirqHookProcessEvents(void)
{
	T1CNTL=0;
	if (usbirqData.eventMask & USBIRQ_EVENT_EP5IN){
		if (isFifoEmpty()==0){
			struct UsbISR * msg = (struct UsbISR *)osal_msg_allocate(sizeof(struct UsbISR) );
			msg->msg.event = EVENT_USB_ISR;
			msg->isr = eventSendFifo;
			osal_msg_send(zusbTaskId, (uint8 *)msg);
		}
	}
	if (usbirqData.eventMask & USBIRQ_EVENT_EP2OUT){
		 uint8 oldEndpoint = USBFW_GET_SELECTED_ENDPOINT();
	     USBFW_SELECT_ENDPOINT(2);

		uint8 length = USBFW_GET_OUT_ENDPOINT_COUNT_LOW();
		if (length > MAX_DATE_SIZE_2){
			length = MAX_DATE_SIZE_2;
		}
  	    

   		if (length) {
			struct UsbISR * msg =NULL;
			uint8 code = USBF2;
			switch( code){
			case ENABLE_INFO_MESSAGE:
				usbOn=1;
				break;
			case REQ_RESET:
					msg = (struct UsbISR *)osal_msg_allocate(sizeof(struct UsbISR) );
					msg->msg.event = EVENT_USB_ISR;
					msg->isr = eventReset;
					break;
			case REQ_BIND_TABLE: {
					uint8 addr[2];
					addr[0] = USBF2;
					addr[1] = USBF2;
					struct BindTableRequestMsg * msgReq = (struct BindTableRequestMsg *)osal_msg_allocate(sizeof(struct BindTableRequestMsg) );
					msg = &(msgReq->isr);
					msg->isr = eventBindReq;
					msg->msg.event = EVENT_USB_ISR;
					msgReq->afAddrType.addrMode = Addr16Bit;
					msgReq->afAddrType.addr.shortAddr = *(uint16 *)(addr);
					}
					break;
			case REQ_ACTIVE_EP:{
					struct ReqActiveEndpointsEvent * msgEP = (struct ReqActiveEndpointsEvent *)osal_msg_allocate(sizeof(struct ReqActiveEndpointsEvent) );
					msg = &(msgEP->isr);
					msg->isr = eventActiveEP;
					msg->msg.event = EVENT_USB_ISR;
					msgEP->data[0] = USBF2;
					msgEP->data[1] = USBF2;
					}
					break;
			case REQ_ADD_BIND_TABLE_ENTRY:
					msg = createMsgForBind();
					msg->isr = eventBindRequest;
					break;
			case REQ_REMOVE_BIND_TABLE_ENTRY:
					msg = createMsgForBind();
					msg->isr = eventUnbindRequest;
					break;
			case NODE_POWER_REQUEST:{
					struct ReqPowerNodeMsg * msgReq =(struct ReqPowerNodeMsg *)osal_msg_allocate(sizeof(struct ReqPowerNodeMsg) );
					msg = &(msgReq->isr);
					msg->isr = eventReqPowerNode;
					msg->msg.event = EVENT_USB_ISR;
					msgReq->data[0] = USBF2;			
					msgReq->data[1] = USBF2;	
					}
					break;
			case REQ_IEEE_ADDRESS:{
					struct ReqIeeeAddrMsg * msgReq = (struct ReqIeeeAddrMsg *)osal_msg_allocate(sizeof(struct ReqIeeeAddrMsg) );
					msg = &(msgReq->isr);
					msg->isr = eventReqIeeeAddr;
					msg->msg.event = EVENT_USB_ISR;
					msgReq->data[0] = USBF2;			
					msgReq->data[1] = USBF2;	
					msgReq->requestType = USBF2;
					msgReq->startIndex = USBF2;
					break;
					}
			case WRITE_ATTRIBUTE_VALUE:{
					struct WriteAttributeValueUsbMsg usbMsg;
					uint8  * data = (uint8 *)(&usbMsg);
					uint8  i;
					for(i=0; i < sizeof(struct WriteAttributeValueUsbMsg); i++){
						*data = USBF2;
						data++;
					}
					struct WriteAttributeValueMsg * msgCmd = (struct WriteAttributeValueMsg *)osal_msg_allocate(sizeof(struct WriteAttributeValueMsg) +sizeof(zclWriteRec_t) + usbMsg.dataValueLen  );
					msg = &(msgCmd->isr);
					msg->isr = eventWriteValue;
					msg->msg.event = EVENT_USB_ISR;
					
					msgCmd->afAddrType.addrMode=afAddr16Bit;
					msgCmd->afAddrType.addr.shortAddr=usbMsg.nwkAddr;
					msgCmd->afAddrType.endPoint=usbMsg.endpoint;
					msgCmd->cluster = usbMsg.cluster;
					msgCmd->writeCmd.numAttr=1;
					msgCmd->writeCmd.attrList->attrID = usbMsg.attributeId;
					msgCmd->writeCmd.attrList->dataType=usbMsg.dataType;
					data = ((uint8 *)msgCmd) + sizeof(struct WriteAttributeValueMsg) +sizeof(zclWriteRec_t);
					msgCmd->writeCmd.attrList->attrData = data;
					for(i=0; i < usbMsg.dataValueLen; i++){
						*data = USBF2;
						data++;
					}
					}
					break;
			case SEND_CMD:{
					struct SendCmdUsbMsg usbMsg;
					uint8  * data = (uint8 *)(&usbMsg);
					uint8  i;
					for(i=0; i < sizeof(struct SendCmdUsbMsg); i++){
						*data = USBF2;
						data++;
					}
					struct SendCmdMsg * msgCmd = (struct SendCmdMsg *)osal_msg_allocate(sizeof(struct SendCmdMsg) +usbMsg.dataLen  );
					msg = &(msgCmd->isr);
					msg->isr = eventSendCmd;
					msg->msg.event = EVENT_USB_ISR;
					msgCmd->cluster =usbMsg.cluster;
					msgCmd->cmdClusterId = usbMsg.cmdClusterId;
					msgCmd->afAddrType.addr.shortAddr= usbMsg.nwkAddr;
					msgCmd->afAddrType.addrMode = afAddr16Bit;
					msgCmd->afAddrType.endPoint = usbMsg.endpoint;
					msgCmd->dataLen = usbMsg.dataLen;
					
					data = (uint8 *)(msgCmd->data);
					for(i=0; i < usbMsg.dataLen; i++){
						*data = USBF2;
						data++;
					}	
					
					}
					break;
			case REQ_ATTRIBUTE_VALUES: {
				    struct ReqAttributeValueMsg attr;
					uint8  * data = (uint8 *)(&attr);
					uint8  i;
					for(i=0; i < sizeof(struct ReqAttributeValueMsg); i++){
						*data = USBF2;
						data++;
					}
					struct ReqAttributeMsg * msgAttr = (struct ReqAttributeMsg *)osal_msg_allocate(sizeof(struct ReqAttributeMsg) +attr.numAttributes* sizeof(uint16)  );
					msg = &(msgAttr->isr);
					msg->isr = attributeValue;
					msg->msg.event = EVENT_USB_ISR;
					
					msgAttr->afAddrType.addr.shortAddr = attr.nwkAddr;
					msgAttr->afAddrType.addrMode = afAddr16Bit;
					msgAttr->afAddrType.endPoint = attr.endpoint;
					
					msgAttr->numAttr = attr.numAttributes;
					data = (uint8 *)&msgAttr->attrID;
					for (uint8 i=0; i < attr.numAttributes; i++){
						*data = USBF2;
						data++;
						*data = USBF2;
						data++;
					}
					msgAttr->cluster = attr.cluster;
					osal_msg_send(zusbTaskId, (uint8 *)msg);
					break;
				}
			case REQ_DEVICE_INFO:{
				struct ReqDeviceInformationEvent * msgEP = (struct ReqDeviceInformationEvent *)osal_msg_allocate(sizeof(struct ReqDeviceInformationEvent) );
				msg = &(msgEP->isr);
				msg->isr = eventDeviceInfo;
				msg->msg.event = EVENT_USB_ISR;
				msgEP->data[0] = USBF2;
				msgEP->data[1] = USBF2;
				}
				break;
					
			}
			if (msg != NULL) {
				uint8 low = T1CNTL;
				uint8 hi = T1CNTH;
				msg->time=BUILD_UINT16(low,hi);
				osal_msg_send(zusbTaskId, (uint8 *)msg);
			}
			/*uint8 __generic *pTemp = rxData;
      		do {
         		*(pTemp++) = USBF2;
      		} while (--length);*/
   		}
      
		USBFW_ARM_OUT_ENDPOINT();
		USBFW_SELECT_ENDPOINT(oldEndpoint);
	}
}
Ejemplo n.º 3
0
//For each event in FIFO, build a message line for repeatereventlistener and send it
//This procedure accesses eventFifo, but there is no need for synchronization (with main repeater process)
//because we got our own copy of memory when kernel started us  
static int doEventWork(void)
{
    connectionEvent *connEv;
    sessionEvent *sessEv;
    startEndEvent *seEv;
    int eventNum;
    repeaterEvent ev;
    int msgLen;
    
    #ifdef EVENTS_USE_LISTENER
    int connection;
    char eventMessageToListener[MAX_EVENT_MSG_LEN];
    char eventListenerIp[MAX_IP_LEN];
    if (strcmp(eventHandlerType,"eventlistener") == 0) {
		connection = openConnectionToEventListener(eventListenerHost, eventListenerPort, eventListenerIp, MAX_IP_LEN);  
		if (-1 != connection) {
			while(!isFifoEmpty()) {
				ev = eventFifo[fifoTailInd];
				itemsInFifo--;
				fifoTailInd = advanceFifoIndex(fifoTailInd);
				
				eventNum = ev.eventNum;
				
				switch (eventNum) {
					case VIEWER_CONNECT:
					case VIEWER_DISCONNECT:
					case SERVER_CONNECT:
					case SERVER_DISCONNECT:
						connEv = (connectionEvent *) ev.extraInfo;
						msgLen = snprintf(eventMessageToListener, MAX_EVENT_MSG_LEN, 
							"EvMsgVer:%d,EvNum:%d,Time:%ld,Pid:%d,TblInd:%d,Code:%ld,Mode:%d,Ip:%d.%d.%d.%d\n",
							REP_EVENT_VERSION, eventNum, ev.timeStamp, ev.repeaterProcessId, 
							connEv -> tableIndex, connEv -> code, connEv -> connMode, 
							connEv->peerIp.a,connEv->peerIp.b,connEv->peerIp.c,connEv->peerIp.d);  
						break;
					
					case VIEWER_SERVER_SESSION_START:
					case VIEWER_SERVER_SESSION_END:
						sessEv = (sessionEvent *) ev.extraInfo;
						msgLen = snprintf(eventMessageToListener, MAX_EVENT_MSG_LEN, 
							"EvMsgVer:%d,EvNum:%d,Time:%ld,Pid:%d,SvrTblInd:%d,VwrTblInd:%d,"
							"Code:%ld,Mode:%d,SvrIp:%d.%d.%d.%d,VwrIp:%d.%d.%d.%d\n",
							REP_EVENT_VERSION, eventNum, ev.timeStamp, ev.repeaterProcessId, 
							sessEv -> serverTableIndex, sessEv -> viewerTableIndex, sessEv -> code, sessEv -> connMode, 
							sessEv->serverIp.a, sessEv->serverIp.b, sessEv->serverIp.c, sessEv->serverIp.d,
							sessEv->viewerIp.a, sessEv->viewerIp.b, sessEv->viewerIp.c, sessEv->viewerIp.d);  
						break;
					
					case REPEATER_STARTUP:
					case REPEATER_SHUTDOWN:
					case REPEATER_HEARTBEAT:
						seEv = (startEndEvent *) ev.extraInfo;
						msgLen = snprintf(eventMessageToListener, MAX_EVENT_MSG_LEN, 
							"EvMsgVer:%d,EvNum:%d,Time:%ld,Pid:%d,MaxSessions:%d\n",
							REP_EVENT_VERSION, eventNum, ev.timeStamp, ev.repeaterProcessId, seEv -> maxSessions);  
						break;
					
					default:
						msgLen = 0;
						strlcpy(eventMessageToListener, "\n", MAX_EVENT_MSG_LEN);
						break;
				}
				
				if (msgLen > 0) { 
					writeExact(connection, eventMessageToListener, 
						strlen(eventMessageToListener), TIMEOUT_5SECS);
				        
				    debug(LEVEL_3, "%s", eventMessageToListener);
				}
			}
			close(connection);
		}
	}
	#endif //EVENTS_USE_LISTENER
	#ifdef EVENTS_USE_MYSQL
	char eventMessageSQL[MAX_EVENT_SQL_LEN];
	debug(LEVEL_3,"Event handler type: %s, length: %i, strcmp: %i\n",eventHandlerType,strlen(eventHandlerType),strcmp(eventHandlerType,"mysql"));
	if (strcmp(eventHandlerType,"mysql") == 0) {
		int status = 0;
		MYSQL mysql;
		mysql_init(&mysql);
		if (!mysql_real_connect(&mysql,mysqlHost,mysqlUser,mysqlPass,mysqlDb,0,NULL,0))
		{
			debug(LEVEL_1, "Failed to connect to database (%s:%i, %s): Error: %s\n",mysqlHost,mysqlPort,mysqlDb,mysql_error(&mysql));
		}
		else
		{
			debug(LEVEL_3,"Connected to MySQL Database\n");
			while(!isFifoEmpty()) {
				ev = eventFifo[fifoTailInd];
				itemsInFifo--;
				fifoTailInd = advanceFifoIndex(fifoTailInd);
				
				eventNum = ev.eventNum;
				char cuid_str[36];
				char puid_str[36];
				char cuid_str2[36];
				memset(cuid_str, 0, 36);
				memset(puid_str, 0, 36);
    		memset(cuid_str2, 0, 36);
    
				switch (eventNum) {
					case VIEWER_CONNECT:
						status = 1;
						connEv = (connectionEvent *) ev.extraInfo;
		    		uuid_unparse(connEv->uid,cuid_str);
		    		uuid_unparse(process_uid,puid_str);
						msgLen = snprintf(eventMessageSQL, MAX_EVENT_SQL_LEN,
							"INSERT INTO viewers (uid,repeater_uid,lasttime,status,table_index,code,mode,ip) VALUES ('%s','%s',%ld,%d,%d,%ld,%d,'%d.%d.%d.%d');\n",
							cuid_str,puid_str, ev.timeStamp, status,connEv->tableIndex,connEv->code,connEv->connMode, 
							connEv->peerIp.a,connEv->peerIp.b,connEv->peerIp.c,connEv->peerIp.d);  
						break;
					case VIEWER_DISCONNECT:
						status = 0;
						connEv = (connectionEvent *) ev.extraInfo;
		    		uuid_unparse(connEv->uid,cuid_str);
						msgLen = snprintf(eventMessageSQL, MAX_EVENT_SQL_LEN,
							"UPDATE viewers SET lasttime = %ld,status = %d WHERE uid = '%s';\n",
							ev.timeStamp, status,cuid_str);
						break;
					case SERVER_CONNECT:
						status = 1;
						connEv = (connectionEvent *) ev.extraInfo;
		    		uuid_unparse(connEv->uid,cuid_str);
		    		uuid_unparse(process_uid,puid_str);
						msgLen = snprintf(eventMessageSQL, MAX_EVENT_SQL_LEN,
							"INSERT INTO servers (uid,repeater_uid,lasttime,status,table_index,code,mode,ip) VALUES ('%s','%s',%ld,%d,%d,%ld,%d,'%d.%d.%d.%d');\n",
							cuid_str,puid_str,ev.timeStamp, status,connEv->tableIndex,connEv->code,connEv->connMode, 
							connEv->peerIp.a,connEv->peerIp.b,connEv->peerIp.c,connEv->peerIp.d);  
						break;
					case SERVER_DISCONNECT:
						status = 0;
						connEv = (connectionEvent *) ev.extraInfo;
		    		uuid_unparse(connEv->uid,cuid_str);
						msgLen = snprintf(eventMessageSQL, MAX_EVENT_SQL_LEN,
							"UPDATE servers SET lasttime = %ld,status = %d WHERE uid = '%s';\n",
							ev.timeStamp, status,cuid_str);
						break;
					
					case VIEWER_SERVER_SESSION_START:
						status = 1;
						sessEv = (sessionEvent *) ev.extraInfo;
				 		uuid_unparse(sessEv->server_uid,cuid_str);
    				uuid_unparse(sessEv->viewer_uid,cuid_str2);
    				uuid_unparse(process_uid,puid_str);
						msgLen = snprintf(eventMessageSQL, MAX_EVENT_SQL_LEN, 
							"INSERT INTO sessions (repeater_uid,status,lasttime,server_index,server_ip,server_uid,viewer_index,viewer_ip,viewer_uid,code,mode) "
							"VALUES ('%s',%d,%ld,%d,'%d.%d.%d.%d','%s',%d,'%d.%d.%d.%d','%s',%ld,%d);\n",
							puid_str,status,ev.timeStamp,
							sessEv -> serverTableIndex,sessEv->serverIp.a, sessEv->serverIp.b, sessEv->serverIp.c, sessEv->serverIp.d,cuid_str,
							sessEv -> viewerTableIndex,sessEv->viewerIp.a, sessEv->viewerIp.b, sessEv->viewerIp.c, sessEv->viewerIp.d,cuid_str2,
							sessEv -> code, sessEv -> connMode);  
						break;
					
					case VIEWER_SERVER_SESSION_END:
						status = 0;
						sessEv = (sessionEvent *) ev.extraInfo;
						uuid_unparse(process_uid,puid_str);
				 		uuid_unparse(sessEv->server_uid,cuid_str);
    				uuid_unparse(sessEv->viewer_uid,cuid_str2);
						msgLen = snprintf(eventMessageSQL, MAX_EVENT_SQL_LEN, 
							"UPDATE sessions SET status=%d,lasttime=%ld WHERE repeater_uid='%s' AND server_uid='%s' AND viewer_uid='%s';\n",
							status,ev.timeStamp,puid_str,cuid_str,cuid_str2);
						break;
					
					case REPEATER_STARTUP:
						status = 1;
						seEv = (startEndEvent *) ev.extraInfo;
						uuid_unparse(process_uid,puid_str);
						msgLen = snprintf(eventMessageSQL, MAX_EVENT_SQL_LEN, 
							"INSERT INTO repeaters (uid,process_id,lasttime,status,maxsessions,ip,server_port,viewer_port) VALUES ('%s',%d,%ld,%d,%d,'%s',%d,%d);\n",
							puid_str,ev.repeaterProcessId,ev.timeStamp, status, seEv -> maxSessions, ownIpAddress,serverPort,viewerPort);  
						break;
					case REPEATER_SHUTDOWN:
						status = 0;
						seEv = (startEndEvent *) ev.extraInfo;
						uuid_unparse(process_uid,puid_str);
						msgLen = snprintf(eventMessageSQL, MAX_EVENT_SQL_LEN, 
							"UPDATE repeaters SET lasttime=%ld,status=%d WHERE uid='%s';\n",
							ev.timeStamp, status, puid_str);
						break;
					case REPEATER_HEARTBEAT:
						uuid_unparse(process_uid,puid_str);
						msgLen = snprintf(eventMessageSQL, MAX_EVENT_SQL_LEN, 
							"UPDATE repeaters SET lasttime=%ld WHERE uid='%s';\n",
							ev.timeStamp, puid_str);
						break;
					default:
						msgLen = 0;
						strlcpy(eventMessageSQL, "\n", MAX_EVENT_SQL_LEN);
						break;
				}
				
				if (msgLen > 0) { 
					mysql_query(&mysql,eventMessageSQL);
					if(mysql_errno(&mysql))
					{
						debug(LEVEL_1,"MYSQL ERROR: %s\n",mysql_error(&mysql));
					}
					debug(LEVEL_1, "%s", eventMessageSQL);
				}
			}
			mysql_close(&mysql);
		}		
	}
	#endif //EVENTS_USE_MYSQL
	return 0;
}