/** * Open a socket connection to the proxy server * @param serverName Name of the server, i.e. "localhost" * @param port Port number to connect with, i.e. DEFAULT_PROXY_PORT */ error_t clientsocket_open(const char *serverName, int port) { struct sockaddr_in serverAddress; struct hostent *server; assert(serverName); SYSLOG_INFO("Attempting to open socket to %s on port %d", serverName, port); gTerminate = false; socketFd = socket(AF_INET, SOCK_STREAM, 0); if ((socketFd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { SYSLOG_ERR("ERROR opening socket"); return -1; } if ((server = gethostbyname(serverName)) == NULL) { SYSLOG_ERR("ERROR, no such host\n"); return -1; } bzero((char *) &serverAddress, sizeof(serverAddress)); serverAddress.sin_family = AF_INET; memcpy((char *) server->h_addr, (char *) &serverAddress.sin_addr.s_addr, server->h_length); serverAddress.sin_port = htons(port); SYSLOG_INFO("Connecting..."); if (connect(socketFd, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0) { SYSLOG_ERR("ERROR connecting"); return FAIL; } SYSLOG_INFO("Connection established on fd %d", socketFd); // Initialize the thread pthread_attr_init(&sThreadAttr); // Will run detached from the main dispatcher thread pthread_attr_setdetachstate(&sThreadAttr, PTHREAD_CREATE_DETACHED); // Round robin schedule is fine when processing is extremely low pthread_attr_setschedpolicy(&sThreadAttr, SCHED_RR); // Create the thread if (pthread_create(&sThreadId, &sThreadAttr, &_clientCommThread, NULL)) { SYSLOG_ERR("Creating proxy thread failed: %s", strerror(errno)); clientsocket_close(); return FAIL; } return SUCCESS; }
/** * Push measurements now. This is a cloud- and iotsdk-friendly way to get * a p="1" string through a few sockets and buffers into the outbound message, * which will trigger the proxy to dump the entire contents of the buffer now. * This works because the server ignores the p="1" attribute * * @param deviceId the unique ID of the measurement to push now * @return SUCCESS if we will push the measurement now */ error_t iotxml_pushMeasurementNow(const char *deviceId) { char xml[IOTGEN_ADD_REMOVE_XML_SIZE]; bzero(xml, IOTGEN_ADD_REMOVE_XML_SIZE); snprintf(xml, IOTGEN_ADD_REMOVE_XML_SIZE, "<measure deviceId=\"%s\" p=\"1\" />", deviceId); SYSLOG_INFO("Pushing measurement for device %s now", deviceId); return application_send(xml, strlen(xml)); }
/** * Alert to the ESP that a device can no longer be contacted and may not be in * control of the network * @param deviceId The unique ID of the device * @return SUCCESS if we will declare the device is not present to the server */ error_t iotxml_alertDeviceIsGone(const char *deviceId) { char xml[IOTGEN_ADD_REMOVE_XML_SIZE]; bzero(xml, IOTGEN_ADD_REMOVE_XML_SIZE); snprintf(xml, IOTGEN_ADD_REMOVE_XML_SIZE, "<alert deviceId=\"%s\" type=\"noRead\" />", deviceId); SYSLOG_INFO("Alerting that device %s is gone", deviceId); return application_send(xml, strlen(xml)); }
/** * Declare to the ESP that a new device is available to control * @param deviceId The unique ID of the device * @param deviceType The device type * @return SUCCESS if we will declare the device to the server */ error_t iotxml_addDevice(const char *deviceId, int deviceType) { char xml[IOTGEN_ADD_REMOVE_XML_SIZE]; bzero(xml, IOTGEN_ADD_REMOVE_XML_SIZE); snprintf(xml, IOTGEN_ADD_REMOVE_XML_SIZE, "<add deviceId=\"%s\" deviceType=\"%d\" />", deviceId, deviceType); SYSLOG_INFO("Adding device %s of type %d", deviceId, deviceType); return application_send(xml, strlen(xml)); }
/** * Create XML to represent and convey the result of a command back to the server * @param commandId The command ID as the server presented to us * @param result The result code for the command * @return SUCCESS if we will send the response back to the server */ error_t iotxml_sendResult(int commandId, result_code_e result) { char xmlResult[IOTGEN_RESULT_XML_SIZE]; bzero(xmlResult, IOTGEN_RESULT_XML_SIZE); snprintf(xmlResult, IOTGEN_RESULT_XML_SIZE, "<response cmdId=\"%d\" result=\"%d\"/>", commandId, result); SYSLOG_INFO("Sending result: %s", xmlResult); return application_send(xmlResult, strlen(xmlResult)); }
static int bin_sw_proc_msg( zw_api_ctx_S *ctx, const u8* frame, u8 nodeid ) { int val = -1; SYSLOG_DEBUG( "COMMAND_CLASS_SWITCH_BINARY - processing message" ); if ((unsigned char)frame[6] == SWITCH_BINARY_SET) { SYSLOG_DEBUG( "SWITCH_BINARY_SET received from node %d value %d", nodeid,(unsigned char)frame[7]); val = frame[7]; } else if ((unsigned char)frame[6] == SWITCH_BINARY_GET) { SYSLOG_DEBUG( "SWITCH_BINARY_GET received from node %d value %d", nodeid,(unsigned char)frame[7]); val = frame[7]; } else if ((unsigned char)frame[6] == SWITCH_BINARY_REPORT) { SYSLOG_DEBUG( "SWITCH_BINARY_REPORT received from node %d value %d", nodeid,(unsigned char)frame[7]); val = frame[7]; } else { SYSLOG_INFO( "%i received from node %d", frame[6], nodeid); goto out; } pthread_mutex_lock( &val_lock ); if ( 0 != zw_node_set_state( nodeid, val ) ) SYSLOG_DEBUG( "Setting node bin switch state failed" ); sw_val = val; pthread_cond_broadcast( &sw_value ); pthread_mutex_unlock( &val_lock ); out: return 0; }
static int toggle_sw_proc_msg( zw_api_ctx_S *ctx, const u8* frame, u8 nodeid ) { int val = -1; SYSLOG_DEBUG( "COMMAND_CLASS_BINARY_TOGGLE_SWITCH - processing message" ); if ((unsigned char)frame[6] == SWITCH_TOGGLE_BINARY_SET) { SYSLOG_DEBUG( "SWITCH_TOGGLE_BINARY_SET received from node %d value %d", nodeid,(unsigned char)frame[7]); val = frame[7]; } else if ((unsigned char)frame[6] == SWITCH_TOGGLE_BINARY_GET) { SYSLOG_DEBUG( "SWITCH_TOGGLE_BINARY_GET received from node %d value %d", nodeid,(unsigned char)frame[7]); val = frame[7]; } else if ((unsigned char)frame[6] == SWITCH_TOGGLE_BINARY_REPORT) { SYSLOG_DEBUG( "SWITCH_TOGGLE_BINARY_REPORT received from node %d value %d", nodeid,(unsigned char)frame[7]); val = frame[7]; } else { SYSLOG_INFO( "%i received from node %d", frame[6], nodeid); goto out; } pthread_mutex_lock( &val_lock ); tsw_val = val; pthread_cond_broadcast( &tsw_value ); pthread_mutex_unlock( &val_lock ); out: return 0; }
virtual void OnConnectIndication( int aReason, IDIPCTransport *aTrpt, IDIPCAcceptorConnectorId *aRequestId) { SYSLOG_INFO("ProcessB::OnConnectIndication"); m_transport = aTrpt; aTrpt->OpenWithSink(this); //aTrpt->SendData("hello",strlen("hello")); }
/** * Once we found a new device at some IP address, we attempt to either grab * the gadget_t pointer from our gadgetmanager and update it... or if it * doesn't exist, we create a new gadget. In either case, we query the * gadget for metadata details. * * The gadgetmanager_add(...) will happily return SUCCESS without making * multiple copies of the gadget if it is already tracking the gadget at that * IP address. */ void _gadgetdiscovery_poll(const char *ip) { gadget_t gadget; gadget_t *gadgetPtr; assert(ip); if ((gadgetPtr = gadgetmanager_getByIp(ip)) == NULL) { gadgetPtr = &gadget; bzero(gadgetPtr, sizeof(gadget_t)); strcpy(gadgetPtr->ip, ip); SYSLOG_INFO("[gadget] Creating new device with IP %s", gadgetPtr->ip); } else { SYSLOG_INFO("[gadget] Refreshing device IP %s", gadgetPtr->ip); } if(_gadgetdiscovery_captureGadgetDetails(gadgetPtr) == SUCCESS) { gadgetmanager_add(gadgetPtr); } }
/** * Close off the last tag and send the message. This will allow other message * creating functions to create a new message using iotxml_newMsg(...) * * @param destMsg Pointer to the start of the destination message * @param maxSize Maximum size of the message buffer */ error_t iotxml_send(char *destMsg, int maxSize) { int totalSize = strlen(destMsg); if(lastParamType >= 0) { // Close off the last tag snprintf(destMsg + strlen(destMsg), maxSize - totalSize, "</%s>", paramTypeMap[lastParamType]); } SYSLOG_INFO("Send: %s\n", destMsg); lastParamType = -1; inProgress = false; return application_send(destMsg, strlen(destMsg)); }
/** * Thread for socket receive communications */ static void *_clientCommThread(void *params) { char inboundMsg[CLIENTSOCKET_INBOUND_MSGSIZE]; // Main loop while (!gTerminate) { memset(inboundMsg, 0, sizeof(inboundMsg)); if(libpipecomm_read(socketFd, inboundMsg, CLIENTSOCKET_INBOUND_MSGSIZE) > 0) { SYSLOG_DEBUG("[client] Received: %s", inboundMsg); application_receive(inboundMsg, strlen(inboundMsg)); } } SYSLOG_INFO("*** Exiting Client Socket Thread ***"); pthread_exit(NULL); return NULL; }
/** * Login * @param username * @param password * @return Application API key, or NULL if we couldn't log in */ error_t login_doLogin(const char *username, const char *password) { char baseUrl[PATH_MAX]; char url[PATH_MAX]; char rxBuffer[PROXY_MAX_MSG_LEN]; char headerPassword[PROXY_HEADER_PASSWORD_LEN]; http_param_t params; login_info_t loginInfo; bzero(¶ms, sizeof(params)); xmlSAXHandler saxHandler = { NULL, // internalSubsetHandler, NULL, // isStandaloneHandler, NULL, // hasInternalSubsetHandler, NULL, // hasExternalSubsetHandler, NULL, // resolveEntityHandler, NULL, // getEntityHandler, NULL, // entityDeclHandler, NULL, // notationDeclHandler, NULL, // attributeDeclHandler, NULL, // elementDeclHandler, NULL, // unparsedEntityDeclHandler, NULL, // setDocumentLocatorHandler, NULL, // startDocument NULL, // endDocument _login_xml_startElementHandler, // startElement NULL, // endElement NULL, // reference, _login_xml_charactersHandler, //characters NULL, // ignorableWhitespace NULL, // processingInstructionHandler, NULL, // comment NULL, // warning NULL, // error NULL, // fatal }; // Read the activation URL from the configuration file if(libconfigio_read(proxycli_getConfigFilename(), CONFIGIO_ACTIVATION_URL_TOKEN_NAME, baseUrl, sizeof(baseUrl)) == -1) { printf("Couldn't read %s in file %s, writing default value\n", CONFIGIO_ACTIVATION_URL_TOKEN_NAME, proxycli_getConfigFilename()); libconfigio_write(proxycli_getConfigFilename(), CONFIGIO_ACTIVATION_URL_TOKEN_NAME, DEFAULT_ACTIVATION_URL); strncpy(baseUrl, DEFAULT_ACTIVATION_URL, sizeof(baseUrl)); } snprintf(url, sizeof(url), "%s/login?username=%s", baseUrl, username); snprintf(headerPassword, sizeof(headerPassword), "PASSWORD: %s", password); SYSLOG_INFO("Logging in..."); SYSLOG_INFO("Contacting URL %s\n", url); params.verbose = TRUE; params.timeouts.connectTimeout = HTTPCOMM_DEFAULT_CONNECT_TIMEOUT_SEC; params.timeouts.transferTimeout = HTTPCOMM_DEFAULT_TRANSFER_TIMEOUT_SEC; params.password = headerPassword; libhttpcomm_sendMsg(NULL, CURLOPT_HTTPGET, url, NULL, NULL, NULL, 0, rxBuffer, sizeof(rxBuffer), params, NULL); SYSLOG_INFO("Server returned: \n%s\n", rxBuffer); loginInfo.resultCode = -1; if ( 0 == xmlSAXUserParseMemory(&saxHandler, &loginInfo, rxBuffer, strlen(rxBuffer)) ) { if(loginInfo.resultCode == 0) { printf("Login successful!\n"); SYSLOG_INFO("Login successful"); return SUCCESS; } else { printf("Error logging in\n"); return FAIL; } } printf("Error logging in\n"); return FAIL; }
virtual void OnDisconnect( CAWResult aReason, IDIPCTransport *aTrptId) { SYSLOG_INFO("ProcessB::OnDisconnect"); }
virtual void OnProcessRun(int argc, char** argv, IDIPCProcess *dipcProcess) { SYSLOG_INFO("ProcessB::OnProcessRun"); dipcProcess->CreateClient(m_connector); m_connector->AsycConnect(this,1000,1); }
/** * Get the activation key from the server * @param key Application API key from logging in * @param locationId The location ID for this user * @return the activation key for this device */ char *getactivationinfo_getDeviceActivationKey(const char *key, int locationId) { char url[PATH_MAX]; char baseUrl[PATH_MAX]; char deviceType[8]; char rxBuffer[PROXY_MAX_MSG_LEN]; char headerApiKey[PROXY_HEADER_KEY_LEN]; http_param_t params; getactivationinfo_info_t getActivationInfo; xmlSAXHandler saxHandler = { NULL, // internalSubsetHandler, NULL, // isStandaloneHandler, NULL, // hasInternalSubsetHandler, NULL, // hasExternalSubsetHandler, NULL, // resolveEntityHandler, NULL, // getEntityHandler, NULL, // entityDeclHandler, NULL, // notationDeclHandler, NULL, // attributeDeclHandler, NULL, // elementDeclHandler, NULL, // unparsedEntityDeclHandler, NULL, // setDocumentLocatorHandler, NULL, // startDocument NULL, // endDocument _getactivationinfo_xml_startElementHandler, // startElement NULL, // endElement NULL, // reference, _getactivationinfo_xml_charactersHandler, //characters NULL, // ignorableWhitespace NULL, // processingInstructionHandler, NULL, // comment NULL, // warning NULL, // error NULL, // fatal }; if(activationKeyValid) { return activationKey; } bzero(deviceType, sizeof(deviceType)); bzero(¶ms, sizeof(params)); snprintf(headerApiKey, sizeof(headerApiKey), "FABRUX_API_KEY: %s", login_getApiKey()); // Read the device type from the configuration file if(libconfigio_read(proxycli_getConfigFilename(), CONFIGIO_PROXY_DEVICE_TYPE_TOKEN_NAME, deviceType, sizeof(deviceType)) == -1) { printf("Couldn't read %s in file %s, writing default value\n", CONFIGIO_PROXY_DEVICE_TYPE_TOKEN_NAME, proxycli_getConfigFilename()); libconfigio_write(proxycli_getConfigFilename(), CONFIGIO_PROXY_DEVICE_TYPE_TOKEN_NAME, DEFAULT_PROXY_DEVICETYPE); strncpy(deviceType, DEFAULT_PROXY_DEVICETYPE, sizeof(deviceType)); } // Read the activation URL from the configuration file if(libconfigio_read(proxycli_getConfigFilename(), CONFIGIO_ACTIVATION_URL_TOKEN_NAME, baseUrl, sizeof(baseUrl)) == -1) { printf("Couldn't read %s in file %s, writing default value\n", CONFIGIO_ACTIVATION_URL_TOKEN_NAME, proxycli_getConfigFilename()); libconfigio_write(proxycli_getConfigFilename(), CONFIGIO_ACTIVATION_URL_TOKEN_NAME, DEFAULT_ACTIVATION_URL); strncpy(baseUrl, DEFAULT_ACTIVATION_URL, sizeof(baseUrl)); } snprintf(url, sizeof(url), "%s/locations/%d/deviceActivation/%s", baseUrl, locationId, deviceType); //SYSLOG_INFO("Getting device activation key..."); SYSLOG_INFO("Contacting URL %s\n", url); params.verbose = TRUE; params.timeouts.connectTimeout = HTTPCOMM_DEFAULT_CONNECT_TIMEOUT_SEC; params.timeouts.transferTimeout = HTTPCOMM_DEFAULT_TRANSFER_TIMEOUT_SEC; params.key = headerApiKey; libhttpcomm_sendMsg(NULL, CURLOPT_HTTPGET, url, NULL, NULL, NULL, 0, rxBuffer, sizeof(rxBuffer), params, NULL); SYSLOG_INFO("Server returned: \n%s\n", rxBuffer); getActivationInfo.resultCode = -1; xmlSAXUserParseMemory(&saxHandler, &getActivationInfo, rxBuffer, strlen(rxBuffer)); if(getActivationInfo.resultCode == 0) { printf("Downloaded the secret activation key!\n"); activationKeyValid = true; return activationKey; } else { printf("Error getting activation key. Check the syslogs.\n"); return NULL; } }
/** * Register Device * @return */ error_t registerDevice(void) { char url[PATH_MAX]; char baseUrl[PATH_MAX]; char deviceType[8]; char rxBuffer[PROXY_MAX_MSG_LEN]; char headerApiKey[PROXY_HEADER_KEY_LEN]; char eui64[EUI64_STRING_SIZE+8]; http_param_t params; registrationinfo_info_t registrationInfo; bzero(¶ms, sizeof(params)); xmlSAXHandler saxHandler = { NULL, // internalSubsetHandler, NULL, // isStandaloneHandler, NULL, // hasInternalSubsetHandler, NULL, // hasExternalSubsetHandler, NULL, // resolveEntityHandler, NULL, // getEntityHandler, NULL, // entityDeclHandler, NULL, // notationDeclHandler, NULL, // attributeDeclHandler, NULL, // elementDeclHandler, NULL, // unparsedEntityDeclHandler, NULL, // setDocumentLocatorHandler, NULL, // startDocument NULL, // endDocument _registrationinfo_xml_startElementHandler, // startElement NULL, // endElement NULL, // reference, _registrationinfo_xml_charactersHandler, //characters NULL, // ignorableWhitespace NULL, // processingInstructionHandler, NULL, // comment NULL, // warning NULL, // error NULL, // fatal }; bzero(deviceType, sizeof(deviceType)); bzero(¶ms, sizeof(params)); snprintf(headerApiKey, sizeof(headerApiKey), "FABRUX_API_KEY: %s", login_getApiKey()); // Read the device type from the configuration file if(libconfigio_read(proxycli_getConfigFilename(), CONFIGIO_PROXY_DEVICE_TYPE_TOKEN_NAME, deviceType, sizeof(deviceType)) == -1) { printf("Couldn't read %s in file %s, writing default value\n", CONFIGIO_PROXY_DEVICE_TYPE_TOKEN_NAME, proxycli_getConfigFilename()); libconfigio_write(proxycli_getConfigFilename(), CONFIGIO_PROXY_DEVICE_TYPE_TOKEN_NAME, DEFAULT_PROXY_DEVICETYPE); strncpy(deviceType, DEFAULT_PROXY_DEVICETYPE, sizeof(deviceType)); } // Read the activation URL from the configuration file if(libconfigio_read(proxycli_getConfigFilename(), CONFIGIO_ACTIVATION_URL_TOKEN_NAME, baseUrl, sizeof(baseUrl)) == -1) { printf("Couldn't read %s in file %s, writing default value\n", CONFIGIO_ACTIVATION_URL_TOKEN_NAME, proxycli_getConfigFilename()); libconfigio_write(proxycli_getConfigFilename(), CONFIGIO_ACTIVATION_URL_TOKEN_NAME, DEFAULT_ACTIVATION_URL); strncpy(baseUrl, DEFAULT_ACTIVATION_URL, sizeof(baseUrl)); } eui64_toString(eui64, sizeof(eui64)); // https://developer.presencepro.com/cloud/json/devices/001C42DE23CF-4-33F?productId=4 snprintf(url, sizeof(url), "%s/devices/%s?productId=%s", baseUrl, eui64, deviceType); SYSLOG_INFO("Register device..."); SYSLOG_INFO("Contacting URL %s\n", url); params.verbose = TRUE; params.timeouts.connectTimeout = HTTPCOMM_DEFAULT_CONNECT_TIMEOUT_SEC; params.timeouts.transferTimeout = HTTPCOMM_DEFAULT_TRANSFER_TIMEOUT_SEC; params.key = headerApiKey; libhttpcomm_postMsg(NULL, CURLOPT_HTTPPOST, url, NULL, NULL, "", 0, rxBuffer, sizeof(rxBuffer), params, NULL); SYSLOG_INFO("Server returned: \n%s\n", rxBuffer); registrationInfo.resultCode = -1; if ( 0 == xmlSAXUserParseMemory(&saxHandler, ®istrationInfo, rxBuffer, strlen(rxBuffer)) ) { if(registrationInfo.resultCode == 0) { printf("Register device successful!\n"); SYSLOG_INFO("Register device successful"); return SUCCESS; } else { printf("Error register device\n"); return FAIL; } } printf("Error register device\n"); return FAIL; }