AJ_Status AJOBS_ControllerAPI_StartSoftAPIfNeededOrConnect(AJOBS_Info* obInfo) { AJ_Status status = AJ_OK; // Check if just started if (bFirstStart) { // Check if already Onboarded or in SoftAP mode if (AJOBS_ControllerAPI_IsWiFiClient() || AJOBS_ControllerAPI_IsWiFiSoftAP()) { AJ_InfoPrintf(("CONFIGURE_WIFI_UPON_START was set\n")); return status; } bFirstStart = FALSE; if (obInfo->state == AJOBS_STATE_CONFIGURED_RETRY) { obInfo->state = AJOBS_STATE_CONFIGURED_VALIDATED; } } while (1) { status = AJOBS_ControllerAPI_GotoIdleWiFi(TRUE); // Go into IDLE mode, reset wifi and perfrom scan if (status != AJ_OK) { break; } // Check if require to switch into SoftAP mode. if ((obInfo->state == AJOBS_STATE_NOT_CONFIGURED || obInfo->state == AJOBS_STATE_CONFIGURED_ERROR || obInfo->state == AJOBS_STATE_CONFIGURED_RETRY)) { AJ_InfoPrintf(("Establishing SoftAP with ssid=%s%s auth=%s\n", obSettings->AJOBS_SoftAPSSID, (obSettings->AJOBS_SoftAPIsHidden ? " (hidden)" : ""), obSettings->AJOBS_SoftAPPassphrase == NULL ? "OPEN" : obSettings->AJOBS_SoftAPPassphrase)); if (obInfo->state == AJOBS_STATE_CONFIGURED_RETRY) { AJ_InfoPrintf(("Retry timer activated\n")); status = AJ_EnableSoftAP(obSettings->AJOBS_SoftAPSSID, obSettings->AJOBS_SoftAPIsHidden, obSettings->AJOBS_SoftAPPassphrase, obSettings->AJOBS_WAIT_BETWEEN_RETRIES); } else { status = AJ_EnableSoftAP(obSettings->AJOBS_SoftAPSSID, obSettings->AJOBS_SoftAPIsHidden, obSettings->AJOBS_SoftAPPassphrase, obSettings->AJOBS_WAIT_FOR_SOFTAP_CONNECTION); } if (status != AJ_OK) { if (AJ_ERR_TIMEOUT == status) { //check for timer elapsed for retry if (obInfo->state == AJOBS_STATE_CONFIGURED_RETRY) { AJ_InfoPrintf(("Retry timer elapsed at %ums\n", obSettings->AJOBS_WAIT_BETWEEN_RETRIES)); obInfo->state = AJOBS_STATE_CONFIGURED_VALIDATED; status = (*obWriteInfo)(obInfo); if (status == AJ_OK) { continue; // Loop back and connect in client mode } } } AJ_WarnPrintf(("Failed to establish SoftAP with status=%s\n", AJ_StatusText(status))); } } else { // Otherwise connect to given configuration and according to error code returned map to relevant onboarding state and set value for LastError and ConnectionResult. status = DoConnectWifi(obInfo); if (status == AJ_OK) { if (obInfo->state == AJOBS_STATE_CONFIGURED_ERROR || obInfo->state == AJOBS_STATE_CONFIGURED_RETRY) { continue; // Loop back and establish SoftAP mode } } else { AJ_WarnPrintf(("Failed to establish connection with current configuration status=%s\n", AJ_StatusText(status))); } } break; // Either connected to (as client) or connected from (as SoftAP) a station } return status; }
AJ_Status AJS_CP_Init(AJ_Object* cpObjects) { AJ_Status status; AJ_Object* w = cpObjects; while (w->path) { ++w; } w->path = "/NotificationActions"; w->interfaces = NotificationActionInterfaces; /* * The control panel object is the only one that gets announced */ cpObjects[0].interfaces = ControlPanelInterfaces; cpObjects[0].flags = AJ_OBJ_FLAG_ANNOUNCED; status = AJCPS_Start(cpObjects, CPSMessageHandler, CallInvolvesWidget, SignalInvolvesWidget, InvolvesRootWidget); if (status == AJ_OK) { AJ_WarnPrintf(("Control panel service succesfully initialized\n")); objectList = cpObjects; AJ_AboutSetShouldAnnounce(); #ifndef NDEBUG if (dbgAJS) { AJ_PrintXML(cpObjects); } #endif } return status; }
/* * This function just returns the work item. If there is data inside that you want * you have to unmarshal it after you receive the work item. */ AJ_Status AJ_WSL_WMI_WaitForWorkItem(uint32_t socket, uint8_t command, wsl_work_item** item, uint32_t timeout) { AJ_Status status; AJ_Time timer; AJ_InitTimer(&timer); // AJ_AlwaysPrintf(("WaitForWorkItem: %x\n", command)); //wsl_work_item* item; status = AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[socket].workRxQueue, item, timeout); timeout -= AJ_GetElapsedTime(&timer, TRUE); if ((status == AJ_OK) && item && *item) { if ((status == AJ_OK) && ((*item)->itemType == WSL_NET_INTERUPT)) { // We don't care about the interrupted signal for any calls using this function AJ_WSL_WMI_FreeWorkItem((*item)); status = AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[socket].workRxQueue, item, timeout); } if ((status == AJ_OK) && ((*item)->itemType == command)) { AJ_InfoPrintf(("AJ_WSL_WMI_WaitForWorkItem(): Received work item %s\n", WSL_WorkItemText(command))); return AJ_OK; } else if ((status == AJ_OK) && ((*item)->itemType == WSL_NET_DISCONNECT)) { AJ_InfoPrintf(("Got disconnect while waiting for %s\n", WSL_WorkItemText(command))); // Clean up the network queues int i; for (i = 0; i < AJ_WSL_SOCKET_MAX; i++) { wsl_work_item* clear; AJ_WSL_SOCKET_CONTEXT[i].valid = FALSE; // Removed any stashed data AJ_BufListFree(AJ_WSL_SOCKET_CONTEXT[i].stashedRxList, 1); // Reallocate a new stash AJ_WSL_SOCKET_CONTEXT[i].stashedRxList = AJ_BufListCreate(); // Reset the queue, any work items are now invalid since the socket was closed while (AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[i].workRxQueue, &clear, 0) == AJ_OK) { AJ_WSL_WMI_FreeWorkItem(clear); } while (AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[i].workTxQueue, &clear, 0) == AJ_OK) { AJ_WSL_WMI_FreeWorkItem(clear); } AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[i].workRxQueue); AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[i].workTxQueue); } AJ_WSL_WMI_FreeWorkItem((*item)); return AJ_ERR_LINK_DEAD; } else if ((status == AJ_OK) && ((*item)->itemType == WSL_NET_DATA_RX)) { // If we got data we want to save it and not throw it away, its still not what we // wanted so we can free the work item as it wont be needed at a higher level AJ_InfoPrintf(("Got data while waiting for %s\n", WSL_WorkItemText(command))); if ((*item)->node->length) { AJ_BufNode* new_node = AJ_BufNodeCreateAndTakeOwnership((*item)->node); AJ_BufListPushTail(AJ_WSL_SOCKET_CONTEXT[socket].stashedRxList, new_node); AJ_WSL_WMI_FreeWorkItem((*item)); return AJ_ERR_NULL; } } else { AJ_WarnPrintf(("AJ_WSL_WMI_WaitForWorkItem(): Received incorrect work item %s, wanted %s\n", WSL_WorkItemText((*item)->itemType), WSL_WorkItemText(command))); // Wrong work item, but return NULL because we can free the item internally AJ_WSL_WMI_FreeWorkItem((*item)); return AJ_ERR_NULL; } } return AJ_ERR_NULL; }
AJ_Status AJS_UnmarshalPropArgs(duk_context* ctx, AJ_Message* msg, uint8_t accessor, duk_idx_t msgIdx) { AJ_Status status; const char* iface; const char* prop; const char* signature; uint32_t propId; uint8_t secure = FALSE; AJ_InfoPrintf(("PushPropArgs\n")); if (accessor == AJ_PROP_GET_ALL) { status = AJ_UnmarshalArgs(msg, "s", &iface); if (status == AJ_OK) { duk_push_string(ctx, iface); /* * Save interface (read-only) so we know how to marshal the reply values */ duk_push_string(ctx, AJS_HIDDEN_PROP("propIface")); duk_dup(ctx, -2); duk_def_prop(ctx, msgIdx, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE); } /* * This call always returns an error status because the interface name we are passing in is * invalid but it will indicate if security is required so we can perform the check below */ AJ_IdentifyProperty(msg, iface, "", &propId, &signature, &secure); } else { status = AJ_UnmarshalArgs(msg, "ss", &iface, &prop); if (status == AJ_OK) { status = AJ_IdentifyProperty(msg, iface, prop, &propId, &signature, &secure); if (status == AJ_OK) { duk_push_string(ctx, iface); duk_push_string(ctx, prop); if (accessor == AJ_PROP_GET) { /* * If we are getting a property save the signature so we know how to marshal the * value in the reply. */ duk_push_string(ctx, AJS_HIDDEN_PROP("propSig")); duk_push_string(ctx, signature); duk_def_prop(ctx, msgIdx, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE); } else { /* * Push the value to set */ status = PushArg(ctx, msg); } } } } /* * If the interface is secure check the message is encrypted */ if ((status == AJ_OK) && secure && !(msg->hdr->flags & AJ_FLAG_ENCRYPTED)) { status = AJ_ERR_SECURITY; AJ_WarnPrintf(("Security violation accessing property\n")); } return status; }
/* * create the WMI request to connect to a socket */ AJ_Status AJ_WSL_NET_socket_connect(AJ_WSL_SOCKNUM sock, uint32_t addr, uint16_t port, uint16_t family) { AJ_Status status; AJ_BufList* connectV4; wsl_work_item* item = NULL; connectV4 = AJ_BufListCreate(); WSL_MarshalPacket(connectV4, WSL_SOCKET, WSL_SOCK_CONNECT, 0x0, AJ_WSL_SOCKET_CONTEXT[sock].targetHandle, port, family, &addr, 0x8); WMI_MarshalHeader(connectV4, 1, 1); AJ_WSL_WMI_PadPayload(connectV4); //AJ_BufListPrintDumpContinuous(connectV4); AJ_WSL_WMI_QueueWorkItem(sock, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CONNECT), AJ_WSL_HTC_DATA_ENDPOINT1, connectV4); do { status = AJ_WSL_WMI_WaitForWorkItem(sock, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CONNECT), &item); if (item) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CONNECT)) { AJ_InfoPrintf(("AJ_WSL_NET_socket_connect(): WORK ITEM RECEIVED\n")); AJ_WSL_WMI_FreeWorkItem(item); break; } else { AJ_WarnPrintf(("AJ_WSL_NET_socket_connect(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); } } while (1); return status; }
int8_t AJSVC_PropertyStore_GetCurrentDefaultLanguageIndex() { const char* currentDefaultLanguage = AJSVC_PropertyStore_GetValue(AJSVC_PROPERTY_STORE_DEFAULT_LANGUAGE); int8_t currentDefaultLanguageIndex = AJSVC_PropertyStore_GetLanguageIndex(currentDefaultLanguage); if (currentDefaultLanguageIndex == AJSVC_PROPERTY_STORE_ERROR_LANGUAGE_INDEX) { currentDefaultLanguageIndex = AJSVC_PROPERTY_STORE_NO_LANGUAGE_INDEX; AJ_WarnPrintf(("Failed to find default language %s defaulting to %s", (currentDefaultLanguage != NULL ? currentDefaultLanguage : "NULL"), propertyStoreDefaultLanguages[AJSVC_PROPERTY_STORE_NO_LANGUAGE_INDEX])); } return currentDefaultLanguageIndex; }
/* * create the WMI request to open a socket on the target device */ int8_t AJ_WSL_NET_socket_open(uint16_t domain, uint16_t type, uint16_t protocol) { AJ_Status status; uint8_t handle = AJ_WSL_SOCKET_MAX; AJ_BufList* open; open = AJ_BufListCreate(); WSL_MarshalPacket(open, WSL_SOCKET, WSL_SOCK_OPEN, 0x0c, domain, type, protocol); WMI_MarshalHeader(open, 1, 1); AJ_WSL_WMI_PadPayload(open); //AJ_BufListPrintDumpContinuous(open); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_OPEN), AJ_WSL_HTC_DATA_ENDPOINT1, open); // wait until the command completes { wsl_work_item* item = NULL; status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_OPEN), &item); if (status != AJ_OK) { AJ_WSL_WMI_FreeWorkItem(item); return -1; } if (item) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_OPEN)) { AJ_InfoPrintf(("AJ_WSL_NET_socket_open(): WORK ITEM RECEIVED\n")); uint16_t WMIEvent; uint32_t reserved; uint32_t _command; uint32_t _handle; uint32_t _error; uint32_t _mode; WMI_Unmarshal(item->node->buffer, "quuuuu", &WMIEvent, &reserved, &_command, &_handle, &_error, &_mode); AJ_InfoPrintf((" Socket Open: handle %08lx error %08lx\n", _handle, _error)); handle = AJ_WSL_FindOpenSocketContext(); if (handle != AJ_WSL_SOCKET_MAX) { AJ_WSL_SOCKET_CONTEXT[handle].targetHandle = _handle; AJ_WSL_SOCKET_CONTEXT[handle].valid = TRUE; AJ_WSL_SOCKET_CONTEXT[handle].domain = domain; AJ_WSL_SOCKET_CONTEXT[handle].type = type; AJ_WSL_SOCKET_CONTEXT[handle].protocol = protocol; } } else { AJ_WarnPrintf(("AJ_WSL_NET_socket_open(): BAD WORK ITEM RECEIVED\n")); } } AJ_WSL_WMI_FreeWorkItem(item); } AJ_Sleep(100); return handle; }
AJ_Status AJS_FactoryReset(void) { AJ_Status status = AJ_OK; AJ_WarnPrintf(("FactoryReset\n")); status = AJSVC_PropertyStore_ResetAll(); if (status != AJ_OK) { return status; } status = AJOBS_ClearInfo(); if (status != AJ_OK) { return status; } AJ_ClearCredentials(); return AJ_ERR_RESTART; }
AJ_Status AJNS_Consumer_Start(uint8_t superAgentMode, AJ_Object* proxyObjects, AJNS_Consumer_OnNotify onNotify, AJNS_Consumer_OnDismiss onDismiss) { AJ_Status status = AJ_OK; appSuperAgentMode = superAgentMode; appProxyObjects = proxyObjects; if (appProxyObjects != NULL) { appProxyObjects[NOTIFICATION_PROXYOBJECT_INDEX] = appSuperAgentMode ? AllProxyObject : NotificationProxyObject; } else { AJ_WarnPrintf(("appProxyObjects is NULL. Setting superAgenMode to FALSE.\n")); appSuperAgentMode = FALSE; status = AJ_ERR_INVALID; } appOnNotify = onNotify; appOnDismiss = onDismiss; return status; }
void AJ_WSL_WMI_ProcessSocketDataResponse(AJ_BufNode* pNodeHTCBody) { int8_t socketIndex; uint32_t u32; uint16_t lead, payloadSize, _port; uint32_t _handle, srcAddr; uint16_t ipv6addr[8]; uint16_t bufferOffset = 0; wsl_work_item** ppWork; wsl_work_item* sockResp; // AJ_DumpBytes("WMI_SOCKET_RESPONSE B", pNodeHTCBody->buffer, pNodeHTCBody->length); // Get the initial bytes of data in the packet WMI_Unmarshal(pNodeHTCBody->buffer, "quuq", &lead, &u32, &_handle, &_port); //AJ_BufNodePullBytes(pNodeHTCBody, 12); bufferOffset += 12; // look for the matching handle in the global context then mark it invalid socketIndex = AJ_WSL_FindSocketContext(_handle); if (socketIndex == INVALID_SOCKET) { AJ_WarnPrintf(("data returned for invalid socket. Handle = %lu\n", _handle)); return; } if (AJ_WSL_SOCKET_CONTEXT[socketIndex].domain == WSL_AF_INET6) { bufferOffset += 6; // Get the IPv6 address and payload size WMI_Unmarshal(pNodeHTCBody->buffer + bufferOffset, "6uq", &ipv6addr, &u32, &payloadSize); // Advance the buffer to the start of the payload bufferOffset += 28; } else { bufferOffset += 2; // Get the IPv4 address WMI_Unmarshal(pNodeHTCBody->buffer + bufferOffset, "4q", &srcAddr, &payloadSize); // Advance the buffer to the start of the payload bufferOffset += 12; } sockResp = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(sockResp, 0, sizeof(wsl_work_item)); sockResp->itemType = WSL_NET_DATA_RX; sockResp->size = payloadSize; sockResp->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); AJ_BufNodePullBytes(sockResp->node, bufferOffset); /// the length of the socket header info header sockResp->node->length = payloadSize; ppWork = &sockResp; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[socketIndex].workRxQueue, ppWork, AJ_TIMER_FOREVER); }
AJ_Status AJ_WSL_ip6config(uint32_t mode, uint8_t* globalAddr, uint8_t* localAddr, uint8_t* gateway, uint8_t* exAddr, uint32_t linkPrefix, uint32_t globalPrefix, uint32_t gwPrefix, uint32_t glbPrefixExt) { AJ_Status status; if (mode != IPCONFIG_QUERY) { AJ_ErrPrintf(("AJ_WSL_ip6config(): Can only query IPV6, cannot use mode %lu\n", mode)); return AJ_ERR_UNEXPECTED; } AJ_BufList* ip6config; ip6config = AJ_BufListCreate(); //First zeros are for v4 WSL_MarshalPacket(ip6config, WSL_SOCKET, WSL_SOCK_IP6CONFIG, 0x60, 0, 0, 0, 0, globalAddr, localAddr, gateway, exAddr, linkPrefix, globalPrefix, gwPrefix, glbPrefixExt); WMI_MarshalHeader(ip6config, 1, 1); AJ_WSL_WMI_PadPayload(ip6config); //AJ_BufListPrintDumpContinuous(ip6config); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IP6CONFIG), AJ_WSL_HTC_DATA_ENDPOINT1, ip6config); { wsl_work_item* item = NULL; status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IP6CONFIG), &item); if (item) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IP6CONFIG)) { AJ_InfoPrintf(("AJ_WSL_ip6config(): WORK ITEM RECEIVED\n")); uint16_t WMIEvent; uint32_t reserved; uint32_t _command; uint32_t _handle; uint32_t _error; uint32_t _mode; uint32_t _ipv4 = 0; uint32_t _ipv4mask = 0; uint32_t _ipv4gateway = 0; WMI_Unmarshal(item->node->buffer, "quuuuuuuu6666uuuu", &WMIEvent, &reserved, &_command, &_handle, &_error, &_mode, _ipv4, _ipv4mask, _ipv4gateway, localAddr, globalAddr, gateway, exAddr, &linkPrefix, &globalPrefix, &gwPrefix, &glbPrefixExt); //AJ_DumpBytes("IPV6", item->node->buffer, 0x60); } else { AJ_WarnPrintf(("AJ_WSL_ip6config(): BAD WORK ITEM RECEIVED\n")); } } AJ_WSL_WMI_FreeWorkItem(item); } return status; }
int16_t AJ_WSL_NET_socket_send(uint32_t socket, uint8_t* data, uint16_t size, uint32_t timeout) { AJ_Status status; AJ_InfoPrintf(("AJ_WSL_NET_socket_send()\n")); AJ_BufList* send; AJ_BufNode* tx_data_node; if (AJ_WSL_SOCKET_CONTEXT[socket].valid == FALSE) { AJ_InfoPrintf(("send on invalid socket %lu\n", socket)); return -1; } send = AJ_BufListCreate(); tx_data_node = AJ_BufListCreateNodeExternalZero(data, size, FALSE); WMI_MarshalSend(send, AJ_WSL_SOCKET_CONTEXT[socket].targetHandle, tx_data_node, size); //send now contains the header info for the two part packet your sending //now write send to the MBOX then the data your sending AJ_WSL_WMI_PadPayload(send); AJ_WSL_WMI_QueueWorkItem(socket, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_DATA_TX), AJ_WSL_HTC_DATA_ENDPOINT2, send); /* * Because these are blocking sends, we need to wait until the data has been passed to the target. */ do { wsl_work_item* item = NULL; status = AJ_WSL_WMI_WaitForWorkItem(socket, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_DATA_TX), &item); if (item) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_DATA_TX)) { AJ_InfoPrintf(("AJ_WSL_NET_socket_send(): WORK ITEM RECEIVED\n")); AJ_WSL_WMI_FreeWorkItem(item); break; } else { AJ_WarnPrintf(("AJ_WSL_NET_socket_send(): BAD WORK ITEM RECEIVED\n")); } } AJ_WSL_WMI_FreeWorkItem(item); } while (1); return size; }
AJ_Status AJ_WSL_NET_scan(void) { AJ_Status status; AJ_BufList* start_scan; wsl_work_item* item; AJ_WSL_NET_BSS_FILTER(1); AJ_WSL_NET_set_scan_params(); AJ_InfoPrintf((("AJ_WSL_NET_scan(): START_SCAN\n"))); start_scan = AJ_BufListCreate(); WSL_MarshalPacket(start_scan, WSL_START_SCAN, 0, 0, 0, 0, 0, 0, 0, 0); WMI_MarshalHeader(start_scan, 1, 1); AJ_WSL_WMI_PadPayload(start_scan); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_SCAN), AJ_WSL_HTC_DATA_ENDPOINT1, start_scan); status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_SCAN), &item, AJ_NET_TIMEOUT); if (item && (status == AJ_OK)) { if (item->itemType == WSL_NET_SCAN) { AJ_InfoPrintf(("AJ_WSL_NET_scan(): WORK ITEM RECEIVED\n")); uint16_t WMIEvent; uint32_t toss; uint32_t error; WMI_Unmarshal(item->node->buffer, "quu", &WMIEvent, &toss, &error); if (error != 0) { AJ_ErrPrintf(("AJ_WSL_NET_scan(): Scan error, scan returned: %u", error)); status = AJ_ERR_INVALID; } } else { AJ_WarnPrintf(("AJ_WSL_NET_scan(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); } return status; }
void AJ_WSL_WMI_ProcessWMIEvent(AJ_BufNode* pNodeHTCBody) { uint16_t eventID; uint16_t info1; uint16_t reserved; int32_t dataUnmarshaled; dataUnmarshaled = WMI_Unmarshal(pNodeHTCBody->buffer, "qqq", &eventID, &info1, &reserved); switch (eventID) { case WSL_WMI_READY_EVENTID: { uint8_t capability; dataUnmarshaled += WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "uuMy", &AJ_WSL_TargetFirmware.target_ver, &AJ_WSL_TargetFirmware.abi_ver, &deviceMAC, &capability); AJ_InfoPrintf(("WMI_READY, version A %08lx, version B %08lx capability %x\n", AJ_WSL_TargetFirmware.target_ver, AJ_WSL_TargetFirmware.abi_ver, capability)); AJ_InfoPrintf(("Device MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", deviceMAC[0], deviceMAC[1], deviceMAC[2], deviceMAC[3], deviceMAC[4], deviceMAC[5])); AJ_WSL_HTC_Global.started = TRUE; break; } case WSL_BSS_INFO_EVENTID: { extern void AJ_WSL_BSSINFO_Recv(AJ_BufNode* node); AJ_WSL_BSSINFO_Recv(pNodeHTCBody); break; } case WSL_CMDERROR_EVENTID: { uint16_t commandId; uint8_t error; dataUnmarshaled += WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "qy", &commandId, &error); AJ_InfoPrintf(("WMI_CMDERROR, last command %04x, error code %02x \n", commandId, error)); break; } case WSL_WMI_SCAN_COMPLETE_EVENTID: { // now signal the waiting code that the scan has completed // we can do this by posting an item to the global socket context recv queue // the client will pull off a scan complete event and then continue. wsl_work_item* scanCompleteResponse; wsl_work_item** pItem; scanCompleteResponse = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(scanCompleteResponse, 0, sizeof(wsl_work_item)); scanCompleteResponse->itemType = WSL_NET_SCAN; scanCompleteResponse->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); pItem = &scanCompleteResponse; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[0].workRxQueue, pItem, AJ_TIMER_FOREVER); break; } case WSL_WMI_DISCONNECT_EVENTID: { uint16_t protocolReason; uint8_t bssid[6]; uint16_t disconnectReason; WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "qMq", &protocolReason, &bssid, &disconnectReason); AJ_InfoPrintf(("WMI_DISCONNECT event: protocolReason %x, disconnectReason %x\n", protocolReason, disconnectReason)); if (AJ_WSL_WifiConnectCallback) { (AJ_WSL_WifiConnectCallback)(0); } // now signal the waiting code that the scan has completed // we can do this by posting an item to the global socket context recv queue // the client will pull off a scan complete event and then continue. wsl_work_item* disconnectResponse; wsl_work_item** pItem; disconnectResponse = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(disconnectResponse, 0, sizeof(wsl_work_item)); disconnectResponse->itemType = WSL_NET_DISCONNECT; disconnectResponse->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); pItem = &disconnectResponse; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[0].workRxQueue, pItem, AJ_TIMER_FOREVER); break; } case WSL_WMI_CONNECT_EVENTID: { // now signal the waiting code that the scan has completed // we can do this by posting an item to the global socket context recv queue // the client will pull off a scan complete event and then continue. wsl_work_item* connectResponse; wsl_work_item** pItem; connectResponse = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(connectResponse, 0, sizeof(wsl_work_item)); connectResponse->itemType = WSL_NET_CONNECT; connectResponse->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); pItem = &connectResponse; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[0].workRxQueue, pItem, AJ_TIMER_FOREVER); if (AJ_WSL_WifiConnectCallback) { (AJ_WSL_WifiConnectCallback)(1); } break; } case WSL_WMI_SOCKET_RESPONSE_EVENTID: { uint32_t responseType; uint32_t socketHandle; uint32_t error; WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "uuu", &responseType, &socketHandle, &error); int8_t socketIndex; //AJ_BufListNodePrintDump(pNodeHTCBody, NULL); /* look for the matching handle in the global context then mark it invalid */ switch (responseType) { // some of the commands operate on the global socket context case WSL_SOCK_OPEN: case WSL_SOCK_IPCONFIG: case WSL_SOCK_IP6CONFIG: case WSL_SOCK_STACK_INIT: case WSL_SOCK_IP_HOST_NAME: socketIndex = 0; break; default: { socketIndex = AJ_WSL_FindSocketContext(socketHandle); if (socketIndex == INVALID_SOCKET) { AJ_DumpBytes("INVALID SOCKET DUMP", pNodeHTCBody->buffer, pNodeHTCBody->length); AJ_WarnPrintf(("SOCKET_PING response for invalid socket!\n")); break; } } } if (socketIndex != INVALID_SOCKET) { AJ_Status status = AJ_OK; //push a work item into the Read queue if (status == AJ_OK) { wsl_work_item** ppWork; wsl_work_item* sockResp; sockResp = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(sockResp, 0, sizeof(wsl_work_item)); sockResp->itemType = AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, responseType); //sockResp->size = payloadSize; sockResp->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); ppWork = &sockResp; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[socketIndex].workRxQueue, ppWork, AJ_TIMER_FOREVER); } if ((responseType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CLOSE)) && (socketIndex != INVALID_SOCKET)) { AJ_WSL_SOCKET_CONTEXT[socketIndex].targetHandle = UINT32_MAX; AJ_WSL_SOCKET_CONTEXT[socketIndex].valid = FALSE; } } break; } case WSL_WMI_PEER_NODE_EVENTID: { uint8_t reason; WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "q", &reason); if ((reason == 0) /*&& (AJ_WSL_connectState == AJ_WIFI_CONNECTING)*/) { /* * The 4-way handshake is complete, indicate the state has changed */ if (AJ_WSL_WifiConnectCallback) { (AJ_WSL_WifiConnectCallback)(16 /*RSNA_AUTH_SUCCESS*/); } } break; } // There are several WMI events that aren't parsed. case WSL_REGDOMAIN_EVENTID: case WSL_UNKNOWN2_EVENTID: case WSL_UNKNOWN1_EVENTID: break; default: { AJ_InfoPrintf(("Unknown WMI Event %x\n", eventID)); return; } } AJ_InfoPrintf(("Processed WMI Event: %s\n", WSL_WorkItemText(eventID))); }
AJ_Status AJSVC_PropertyStore_ReadAll(AJ_Message* msg, AJSVC_PropertyStoreCategoryFilter filter, int8_t langIndex) { AJ_Status status = AJ_OK; AJ_Arg array; AJ_Arg array2; AJ_Arg dict; const char* value; AJ_Arg arg; uint8_t rawValue[16]; uint8_t index; const char* ajVersion; AJ_InfoPrintf(("PropertyStore_ReadAll()\n")); status = AJ_MarshalContainer(msg, &array, AJ_ARG_ARRAY); if (status != AJ_OK) { return status; } //AJSVC_PropertyStoreFieldIndices fieldIndex = 0; int fieldIndex = 0; for (; fieldIndex < AJSVC_PROPERTY_STORE_NUMBER_OF_KEYS; fieldIndex++) { #ifdef CONFIG_SERVICE if (propertyStoreProperties[fieldIndex].mode7Public && (filter.bit0About || (filter.bit1Config && propertyStoreProperties[fieldIndex].mode0Write) || (filter.bit2Announce && propertyStoreProperties[fieldIndex].mode1Announce))) { #else if (propertyStoreProperties[fieldIndex].mode7Public && (filter.bit0About || (filter.bit2Announce && propertyStoreProperties[fieldIndex].mode1Announce))) { #endif value = AJSVC_PropertyStore_GetValueForLang((AJSVC_PropertyStoreFieldIndices)fieldIndex, langIndex); if (value == NULL && fieldIndex >= AJSVC_PROPERTY_STORE_NUMBER_OF_MANDATORY_KEYS) { // Non existing values are skipped! AJ_WarnPrintf(("PropertyStore_ReadAll - Failed to get value for field=(name=%s, index=%d) and language=(name=%s, index=%d), skipping.\n", AJSVC_PropertyStore_GetFieldName((AJSVC_PropertyStoreFieldIndices)fieldIndex), (int)fieldIndex, AJSVC_PropertyStore_GetLanguageName(langIndex), (int)langIndex)); } else { if (fieldIndex == AJSVC_PROPERTY_STORE_APP_ID) { if (value == NULL) { AJ_ErrPrintf(("PropertyStore_ReadAll - Failed to get value for mandatory field=(name=%s, index=%d) and language=(name=%s, index=%d), aborting.\n", AJSVC_PropertyStore_GetFieldName((AJSVC_PropertyStoreFieldIndices)fieldIndex), (int)fieldIndex, AJSVC_PropertyStore_GetLanguageName(langIndex), (int)langIndex)); return AJ_ERR_NULL; } status = AJ_MarshalContainer(msg, &dict, AJ_ARG_DICT_ENTRY); if (status != AJ_OK) { return status; } status = AJ_MarshalArgs(msg, "s", propertyStoreProperties[fieldIndex].keyName); if (status != AJ_OK) { return status; } status = AJ_MarshalVariant(msg, "ay"); if (status != AJ_OK) { return status; } status = AJ_HexToRaw(value, 0, rawValue, (size_t)sizeof(rawValue)); if (status != AJ_OK) { return status; } status = AJ_MarshalArg(msg, AJ_InitArg(&arg, AJ_ARG_BYTE, AJ_ARRAY_FLAG, rawValue, sizeof(rawValue))); if (status != AJ_OK) { return status; } status = AJ_MarshalCloseContainer(msg, &dict); if (status != AJ_OK) { return status; } #ifdef CONFIG_SERVICE } else if (fieldIndex == AJSVC_PROPERTY_STORE_MAX_LENGTH) { status = AJ_MarshalContainer(msg, &dict, AJ_ARG_DICT_ENTRY); if (status != AJ_OK) { return status; } status = AJ_MarshalArgs(msg, "s", propertyStoreProperties[fieldIndex].keyName); if (status != AJ_OK) { return status; } status = AJ_MarshalVariant(msg, "q"); if (status != AJ_OK) { return status; } status = AJ_MarshalArgs(msg, "q", DEVICE_NAME_VALUE_LENGTH); if (status != AJ_OK) { return status; } status = AJ_MarshalCloseContainer(msg, &dict); if (status != AJ_OK) { return status; } AJ_InfoPrintf(("Has key [%s] runtime Value [%d]\n", propertyStoreProperties[AJSVC_PROPERTY_STORE_MAX_LENGTH].keyName, DEVICE_NAME_VALUE_LENGTH)); #endif } else if (fieldIndex == AJSVC_PROPERTY_STORE_AJ_SOFTWARE_VERSION) { ajVersion = AJ_GetVersion(); if (ajVersion == NULL) { AJ_ErrPrintf(("PropertyStore_ReadAll - Failed to get value for mandatory field=(name=%s, index=%d) and language=(name=%s, index=%d), aborting.\n", AJSVC_PropertyStore_GetFieldName((AJSVC_PropertyStoreFieldIndices)fieldIndex), (int)fieldIndex, AJSVC_PropertyStore_GetLanguageName(langIndex), (int)langIndex)); return AJ_ERR_NULL; } status = AJ_MarshalContainer(msg, &dict, AJ_ARG_DICT_ENTRY); if (status != AJ_OK) { return status; } status = AJ_MarshalArgs(msg, "s", propertyStoreProperties[fieldIndex].keyName); if (status != AJ_OK) { return status; } status = AJ_MarshalVariant(msg, "s"); if (status != AJ_OK) { return status; } status = AJ_MarshalArgs(msg, "s", ajVersion); if (status != AJ_OK) { return status; } status = AJ_MarshalCloseContainer(msg, &dict); if (status != AJ_OK) { return status; } AJ_InfoPrintf(("Has key [%s] runtime Value [%s]\n", propertyStoreProperties[AJSVC_PROPERTY_STORE_AJ_SOFTWARE_VERSION].keyName, ajVersion)); } else { if (value == NULL) { AJ_ErrPrintf(("PropertyStore_ReadAll - Failed to get value for mandatory field=(name=%s, index=%d) and language=(name=%s, index=%d), aborting.\n", AJSVC_PropertyStore_GetFieldName((AJSVC_PropertyStoreFieldIndices)fieldIndex), (int)fieldIndex, AJSVC_PropertyStore_GetLanguageName(langIndex), (int)langIndex)); return AJ_ERR_NULL; } status = AJ_MarshalContainer(msg, &dict, AJ_ARG_DICT_ENTRY); if (status != AJ_OK) { return status; } status = AJ_MarshalArgs(msg, "s", propertyStoreProperties[fieldIndex].keyName); if (status != AJ_OK) { return status; } status = AJ_MarshalVariant(msg, "s"); if (status != AJ_OK) { return status; } status = AJ_MarshalArgs(msg, "s", value); if (status != AJ_OK) { return status; } status = AJ_MarshalCloseContainer(msg, &dict); if (status != AJ_OK) { return status; } } } } } if (filter.bit0About) { // Add supported languages status = AJ_MarshalContainer(msg, &dict, AJ_ARG_DICT_ENTRY); if (status != AJ_OK) { return status; } status = AJ_MarshalArgs(msg, "s", defaultLanguagesKeyName); if (status != AJ_OK) { return status; } status = AJ_MarshalVariant(msg, "as"); if (status != AJ_OK) { return status; } status = AJ_MarshalContainer(msg, &array2, AJ_ARG_ARRAY); if (status != AJ_OK) { return status; } index = AJSVC_PROPERTY_STORE_NO_LANGUAGE_INDEX; for (; index < AJSVC_PROPERTY_STORE_NUMBER_OF_LANGUAGES; index++) { status = AJ_MarshalArgs(msg, "s", propertyStoreDefaultLanguages[index]); if (status != AJ_OK) { return status; } } status = AJ_MarshalCloseContainer(msg, &array2); if (status != AJ_OK) { return status; } status = AJ_MarshalCloseContainer(msg, &dict); if (status != AJ_OK) { return status; } } status = AJ_MarshalCloseContainer(msg, &array); if (status != AJ_OK) { return status; } return status; } #ifdef CONFIG_SERVICE AJ_Status AJSVC_PropertyStore_Update(const char* key, int8_t langIndex, const char* value) { AJSVC_PropertyStoreFieldIndices fieldIndex = AJSVC_PropertyStore_GetFieldIndex(key); if (fieldIndex == AJSVC_PROPERTY_STORE_ERROR_FIELD_INDEX || fieldIndex >= AJSVC_PROPERTY_STORE_NUMBER_OF_CONFIG_KEYS) { return AJ_ERR_INVALID; } if (!UpdateFieldInRAM(fieldIndex, langIndex, value)) { return AJ_ERR_FAILURE; } return AJ_OK; }
int AJ_Main(void) { AJ_Status status = AJ_OK; uint8_t connected = FALSE; uint8_t done = FALSE; /* * One time initialization before calling any other AllJoyn APIs */ AJ_Initialize(); AJ_RegisterObjects(NULL, proxyObjects); while (!done) { AJ_Message msg; if (!connected) { const char* announceRule = "type='signal',sessionless='t',interface='org.alljoyn.About',member='Announce'"; status = AJ_FindBusAndConnect(&bus, NULL, AJ_CONNECT_TIMEOUT); if (status != AJ_OK) { AJ_WarnPrintf(("AJ_FindBusAndConnect(): failed - sleeping for %d seconds\n", AJ_CONNECT_PAUSE / 1000)); AJ_Sleep(AJ_CONNECT_PAUSE); continue; } AJ_AboutRegisterAnnounceHandlers(peerDescriptions, ArraySize(peerDescriptions)); AJ_BusSetSignalRule(&bus, announceRule, AJ_BUS_SIGNAL_ALLOW); connected = TRUE; } status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT); if (AJ_ERR_TIMEOUT == status) { continue; } if (AJ_OK == status) { switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_JOIN_SESSION): if (msg.hdr->msgType != AJ_MSG_ERROR) { uint32_t result; status = AJ_UnmarshalArgs(&msg, "uu", &result, &sessionId); if (status == AJ_OK) { if (result == AJ_JOINSESSION_REPLY_SUCCESS) { AJ_AlwaysPrintf(("joined session %u\n", sessionId)); DoCat(); } else { AJ_AlwaysPrintf(("joined session rejected %d\n", result)); } } } else { AJ_ErrPrintf(("JoinSession reply was error: %s\n", msg.error)); } break; case AJ_REPLY_ID(BASIC_CLIENT_CAT): if (msg.hdr->msgType != AJ_MSG_ERROR) { AJ_Arg arg; status = AJ_UnmarshalArg(&msg, &arg); if (AJ_OK == status) { AJ_AlwaysPrintf(("cat returned \"%s\"\n", arg.val.v_string)); if (!waitVar) { done = TRUE; } } } else { AJ_ErrPrintf(("Reply was error: %s\n", msg.error)); } break; case AJ_SIGNAL_MP_SESSION_CHANGED_WITH_REASON: { uint32_t sessId; const char* peer; uint32_t added; uint32_t reason; status = AJ_UnmarshalArgs(&msg, "usbu", &sessId, &peer, &added, &reason); if (added) { AJ_AlwaysPrintf(("Member \"%s\" added to session %u\n", peer, sessId)); } else { AJ_AlwaysPrintf(("Member \"%s\" removed from session %u\n", peer, sessId)); } } break; case AJ_SIGNAL_SESSION_LOST_WITH_REASON: AJ_AlwaysPrintf(("Session lost\n")); break; default: /* Pass to the built-in handlers. */ status = AJ_BusHandleBusMessage(&msg); break; } } /* Messages MUST be discarded to free resources. */ AJ_CloseMsg(&msg); if (status == AJ_ERR_READ) { AJ_AlwaysPrintf(("Connection lost\n")); AJ_Disconnect(&bus); exit(0); } } AJ_AlwaysPrintf(("Basic client exiting with status %d.\n", status)); return status; }
/* * read from the mailbox and do something useful with the HTC message. */ void AJ_WSL_HTC_ProcessIncoming(void) { uint16_t lenRead; uint8_t* bufRead; AJ_BufNode* pNodeHTCBody; uint8_t endpointID; uint8_t flags; uint16_t payloadLength; uint8_t controlBytes[2]; AJ_Status status; status = AJ_WSL_ReadFromMBox(AJ_WSL_SPI_MBOX_0, &lenRead, &bufRead); AJ_ASSERT(status == AJ_OK); // now create a AJ_BufList from the data we read pNodeHTCBody = AJ_BufListCreateNodeExternalZero(bufRead, lenRead, FALSE); pNodeHTCBody->flags = 0; // reset the AJ_BUFNODE_EXTERNAL_BUFFER flag, because I own this now. WMI_Unmarshal(pNodeHTCBody->buffer, "yyqyy", &endpointID, &flags, &payloadLength, &controlBytes[0], &controlBytes[1]); AJ_BufNodePullBytes(pNodeHTCBody, 6); //AJ_WSL_WMI_PrintMessage(pNodeHTCBody); AJ_DumpBytes("HTC_CONTROL", pNodeHTCBody->buffer, pNodeHTCBody->length); /* examine the endpoint of the HTC message*/ if ((flags & AJ_WSL_HTC_RECV_TRAILER_PRESENT) && ((payloadLength - controlBytes[0]) > 0)) { switch (endpointID) { case AJ_WSL_HTC_CONTROL_ENDPOINT: { uint16_t* messageID = (uint16_t*)pNodeHTCBody->buffer; AJ_InfoPrintf(("Read HTC control endpoint, messageID %x\n", *messageID)); switch (*messageID) { case AJ_WSL_HTC_MSG_READY_ID: { /* process the message and change state */ uint16_t readyMessageID; WMI_Unmarshal(pNodeHTCBody->buffer, "qqqyyy", &readyMessageID, &AJ_WSL_HTC_Global.creditCount, &AJ_WSL_HTC_Global.creditSize, &AJ_WSL_HTC_Global.maxEndpoints, &AJ_WSL_HTC_Global.HTCVersion, &AJ_WSL_HTC_Global.maxMessagesPerBundle); /* SIDE EFFECT */ AJ_WarnPrintf(("MSG_READY, credit count %x, credit size:%d\n", AJ_WSL_HTC_Global.creditCount, AJ_WSL_HTC_Global.creditSize)); AJ_WSL_HTC_Global.endpoints[AJ_WSL_HTC_CONTROL_ENDPOINT].state = AJ_WSL_HTC_UNINITIALIZED_RECV_READY; break; } case AJ_WSL_HTC_SERVICE_CONNECT_RESPONSE_ID: { AJ_WarnPrintf(("HTC MSG AJ_WSL_HTC_SERVICE_CONNECT_RESPONSE_ID\n")); break; } default: AJ_WarnPrintf(("HTC MSG ID unknown\n")); AJ_DumpBytes("WMI_SOCKET_RESPONSE", pNodeHTCBody->buffer, pNodeHTCBody->length); break; } break; } case AJ_WSL_HTC_DATA_ENDPOINT1: { // AJ_DumpBytes("DATA ENDPOINT WMI ", pNodeHTCBody->buffer, pNodeHTCBody->length); AJ_WSL_WMI_ProcessWMIEvent(pNodeHTCBody); break; } case AJ_WSL_HTC_DATA_ENDPOINT2: case AJ_WSL_HTC_DATA_ENDPOINT3: case AJ_WSL_HTC_DATA_ENDPOINT4: { AJ_DumpBytes("DATA ENDPOINT WMI_SOCKET_RESPONSE", pNodeHTCBody->bufferStart, pNodeHTCBody->length); AJ_WSL_WMI_ProcessSocketDataResponse(pNodeHTCBody); //AJ_InfoPrintf(("Read HTC data endpoint %d\n", htcHdr.endpointID)); // TODO send the data up to the next API level //AJ_WSL_WMI_PrintMessage(pNodeHTCBody); break; } default: AJ_ErrPrintf(("UNKNOWN Endpoint %d", endpointID)); AJ_ASSERT(FALSE); break; } } /* * Trailers can come on any packet */ if (flags & AJ_WSL_HTC_RECV_TRAILER_PRESENT) { uint16_t packetLength; uint8_t trailerLength = controlBytes[0]; packetLength = payloadLength - trailerLength; //AJ_InfoPrintf(("Read HTC RX trailer, length %d\n", htcHdr.controlBytes[0])); AJ_BufNodePullBytes(pNodeHTCBody, packetLength); // consume the packet, leave the trailer /* * handle multiple trailers per HTC message */ while (trailerLength) { uint8_t trailerType; uint8_t length; //AJ_BufListNodePrintDump(pNodeHTCBody, NULL); WMI_Unmarshal(pNodeHTCBody->buffer, "yy", &trailerType, &length); AJ_BufNodePullBytes(pNodeHTCBody, 2); // consume the trailer trailerLength -= 2; switch (trailerType) { case AJ_WSL_HTC_RXTRAILER_CREDIT_REPORT: { uint8_t credits; uint8_t endpoint; WMI_Unmarshal(pNodeHTCBody->buffer, "yy", &endpoint, &credits); AJ_InfoPrintf(("Add %d credits to endpoint %d\n", credits, endpoint)); AJ_WSL_HTC_Global.endpoints[endpoint].txCredits += credits; break; } default: { AJ_InfoPrintf(("HTC trailer: type not handled %d\n", trailerType)); } } trailerLength -= length; AJ_BufNodePullBytes(pNodeHTCBody, length); // consume the trailer } } //intentionally freeing the buffer here AJ_BufListFreeNodeAndBuffer(pNodeHTCBody, NULL); }
AJ_Status AJ_WSL_ipconfig(uint32_t mode, uint32_t* ip, uint32_t* mask, uint32_t* gateway) { AJ_Status status = AJ_ERR_DHCP; uint16_t ipv6[8] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; wsl_work_item* item = NULL; switch (mode) { case (IPCONFIG_QUERY): { AJ_InfoPrintf(("AJ_WSL_ipconfig(): IPCONFIG_QUERY\n")); AJ_BufList* ipconfig; ipconfig = AJ_BufListCreate(); WSL_MarshalPacket(ipconfig, WSL_SOCKET, WSL_SOCK_IPCONFIG, 0x60, 0, ip, mask, gateway, &ipv6, &ipv6, &ipv6, &ipv6, 0, 0, 0, 0); WMI_MarshalHeader(ipconfig, 1, 1); AJ_WSL_WMI_PadPayload(ipconfig); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG), AJ_WSL_HTC_DATA_ENDPOINT1, ipconfig); { status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG), &item); if (item) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG)) { AJ_InfoPrintf(("AJ_WSL_ipconfig(): WORK ITEM RECEIVED\n")); uint16_t WMIEvent; uint32_t reserved; uint32_t _command; uint32_t _handle; uint32_t _error; uint32_t _mode; WMI_Unmarshal(item->node->buffer, "quuuuuuuu", &WMIEvent, &reserved, &_command, &_handle, &_error, &_mode, ip, mask, gateway); if (ip != 0) { status = AJ_OK; } } else { AJ_WarnPrintf(("AJ_WSL_ipconfig(): BAD WORK ITEM RECEIVED\n")); } } } } AJ_WSL_WMI_FreeWorkItem(item); break; case (IPCONFIG_STATIC): AJ_InfoPrintf(("AJ_WSL_ipconfig(): IPCONFIG_STATIC\n")); AJ_BufList* ipconfig_dhcp_static; ipconfig_dhcp_static = AJ_BufListCreate(); WSL_MarshalPacket(ipconfig_dhcp_static, WSL_SOCKET, WSL_SOCK_IPCONFIG, 0x60, 1, ip, mask, gateway, &ipv6, &ipv6, &ipv6, &ipv6, 0, 0, 0, 0); WMI_MarshalHeader(ipconfig_dhcp_static, 1, 1); AJ_WSL_WMI_PadPayload(ipconfig_dhcp_static); //AJ_BufListPrintDumpContinuous(ipconfig_dhcp_static); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG), AJ_WSL_HTC_DATA_ENDPOINT1, ipconfig_dhcp_static); status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG), &item); AJ_WSL_WMI_FreeWorkItem(item); AJ_Sleep(1000); break; case (IPCONFIG_DHCP): AJ_InfoPrintf(("AJ_WSL_ipconfig(): IPCONFIG_DHCP\n")); AJ_BufList* ipconfig_dhcp; ipconfig_dhcp = AJ_BufListCreate(); WSL_MarshalPacket(ipconfig_dhcp, WSL_SOCKET, WSL_SOCK_IPCONFIG, 0x60, 2, ip, mask, gateway, &ipv6, &ipv6, &ipv6, &ipv6, 0, 0, 0, 0); WMI_MarshalHeader(ipconfig_dhcp, 1, 1); AJ_WSL_WMI_PadPayload(ipconfig_dhcp); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG), AJ_WSL_HTC_DATA_ENDPOINT1, ipconfig_dhcp); status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG), &item); AJ_WSL_WMI_FreeWorkItem(item); AJ_Sleep(100); break; } return status; }
AJ_Status AJ_StartService(AJ_BusAttachment* bus, const char* daemonName, uint32_t timeout, uint8_t connected, uint16_t port, const char* name, uint32_t flags, const AJ_SessionOpts* opts ) { AJ_Status status; AJ_Time timer; uint8_t serviceStarted = FALSE; AJ_InfoPrintf(("AJ_StartService(bus=0x%p, daemonName=\"%s\", timeout=%d., connected=%d., port=%d., name=\"%s\", flags=0x%x, opts=0x%p)\n", bus, daemonName, timeout, connected, port, name, flags, opts)); AJ_InitTimer(&timer); while (TRUE) { if (AJ_GetElapsedTime(&timer, TRUE) > timeout) { return AJ_ERR_TIMEOUT; } if (!connected) { AJ_InfoPrintf(("AJ_StartService(): AJ_FindBusAndConnect()\n")); status = AJ_FindBusAndConnect(bus, daemonName, AJ_CONNECT_TIMEOUT); if (status != AJ_OK) { AJ_WarnPrintf(("AJ_StartService(): connect failed: sleeping for %d seconds\n", AJ_CONNECT_PAUSE / 1000)); AJ_Sleep(AJ_CONNECT_PAUSE); continue; } AJ_InfoPrintf(("AJ_StartService(): connected to bus\n")); } /* * Kick things off by binding a session port */ AJ_InfoPrintf(("AJ_StartService(): AJ_BindSessionPort()\n")); status = AJ_BusBindSessionPort(bus, port, opts, 0); if (status == AJ_OK) { break; } AJ_ErrPrintf(("AJ_StartService(): AJ_Disconnect(): status=%s.\n", AJ_StatusText(status))); AJ_Disconnect(bus); } while (!serviceStarted && (status == AJ_OK)) { AJ_Message msg; status = AJ_UnmarshalMsg(bus, &msg, AJ_UNMARSHAL_TIMEOUT); if (status == AJ_ERR_NO_MATCH) { // Ignore unknown messages status = AJ_OK; continue; } if (status != AJ_OK) { AJ_ErrPrintf(("AJ_StartService(): status=%s.\n", AJ_StatusText(status))); break; } switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_BIND_SESSION_PORT): if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_ErrPrintf(("AJ_StartService(): AJ_METHOD_BIND_SESSION_PORT: %s\n", msg.error)); status = AJ_ERR_FAILURE; } else { AJ_InfoPrintf(("AJ_StartService(): AJ_BusRequestName()\n")); status = AJ_BusRequestName(bus, name, flags); } break; case AJ_REPLY_ID(AJ_METHOD_REQUEST_NAME): if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_ErrPrintf(("AJ_StartService(): AJ_METHOD_REQUEST_NAME: %s\n", msg.error)); status = AJ_ERR_FAILURE; } else { AJ_InfoPrintf(("AJ_StartService(): AJ_BusAdvertiseName()\n")); status = AJ_BusAdvertiseName(bus, name, AJ_TRANSPORT_ANY, AJ_BUS_START_ADVERTISING, 0); } break; case AJ_REPLY_ID(AJ_METHOD_ADVERTISE_NAME): if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_ErrPrintf(("AJ_StartService(): AJ_METHOD_ADVERTISE_NAME: %s\n", msg.error)); status = AJ_ERR_FAILURE; } else { serviceStarted = TRUE; } break; default: /* * Pass to the built-in bus message handlers */ AJ_InfoPrintf(("AJ_StartService(): AJ_BusHandleBusMessage()\n")); status = AJ_BusHandleBusMessage(&msg); break; } AJ_CloseMsg(&msg); } if (status == AJ_OK) { status = AJ_AboutInit(bus, port); } else { AJ_WarnPrintf(("AJ_StartService(): AJ_Disconnect(): status=%s\n", AJ_StatusText(status))); AJ_Disconnect(bus); } return status; }
static AJ_Status StartClient(AJ_BusAttachment* bus, const char* daemonName, uint32_t timeout, uint8_t connected, const char* name, uint16_t port, const char** interfaces, uint32_t* sessionId, char* serviceName, const AJ_SessionOpts* opts) { AJ_Status status = AJ_OK; AJ_Time timer; uint8_t found = FALSE; uint8_t clientStarted = FALSE; uint32_t elapsed = 0; char* rule; size_t ruleLen; const char* base = "interface='org.alljoyn.About',sessionless='t'"; const char* impl = ",implements='"; const char** ifaces; AJ_InfoPrintf(("AJ_StartClient(bus=0x%p, daemonName=\"%s\", timeout=%d., connected=%d., interface=\"%p\", sessionId=0x%p, serviceName=0x%p, opts=0x%p)\n", bus, daemonName, timeout, connected, interfaces, sessionId, serviceName, opts)); AJ_InitTimer(&timer); if ((name == NULL && interfaces == NULL) || (name != NULL && interfaces != NULL)) { return AJ_ERR_INVALID; } while (elapsed < timeout) { if (!connected) { status = AJ_FindBusAndConnect(bus, daemonName, AJ_CONNECT_TIMEOUT); elapsed = AJ_GetElapsedTime(&timer, TRUE); if (status != AJ_OK) { elapsed += AJ_CONNECT_PAUSE; if (elapsed > timeout) { break; } AJ_WarnPrintf(("AJ_StartClient(): Failed to connect to bus, sleeping for %d seconds\n", AJ_CONNECT_PAUSE / 1000)); AJ_Sleep(AJ_CONNECT_PAUSE); continue; } AJ_InfoPrintf(("AJ_StartClient(): AllJoyn client connected to bus\n")); } if (name != NULL) { /* * Kick things off by finding the service names */ status = AJ_BusFindAdvertisedName(bus, name, AJ_BUS_START_FINDING); AJ_InfoPrintf(("AJ_StartClient(): AJ_BusFindAdvertisedName()\n")); } else { /* * Kick things off by finding all services that implement the interface */ ruleLen = strlen(base) + 1; ifaces = interfaces; while (*ifaces != NULL) { ruleLen += strlen(impl) + strlen(*ifaces) + 1; ifaces++; } rule = (char*) AJ_Malloc(ruleLen); if (rule == NULL) { status = AJ_ERR_RESOURCES; break; } strcpy(rule, base); ifaces = interfaces; while (*ifaces != NULL) { strcat(rule, impl); if ((*ifaces)[0] == '$') { strcat(rule, &(*ifaces)[1]); } else { strcat(rule, *ifaces); } strcat(rule, "'"); ifaces++; } status = AJ_BusSetSignalRule(bus, rule, AJ_BUS_SIGNAL_ALLOW); AJ_InfoPrintf(("AJ_StartClient(): Client SetSignalRule: %s\n", rule)); AJ_Free(rule); } if (status == AJ_OK) { break; } if (!connected) { AJ_WarnPrintf(("AJ_StartClient(): Client disconnecting from bus: status=%s.\n", AJ_StatusText(status))); AJ_Disconnect(bus); } } if (elapsed > timeout) { AJ_WarnPrintf(("AJ_StartClient(): Client timed-out trying to connect to bus: status=%s.\n", AJ_StatusText(status))); return AJ_ERR_TIMEOUT; } timeout -= elapsed; if (status != AJ_OK) { return status; } *sessionId = 0; if (serviceName != NULL) { *serviceName = '\0'; } while (!clientStarted && (status == AJ_OK)) { AJ_Message msg; status = AJ_UnmarshalMsg(bus, &msg, AJ_UNMARSHAL_TIMEOUT); if ((status == AJ_ERR_TIMEOUT) && !found) { /* * Timeouts are expected until we find a name or service */ if (timeout < AJ_UNMARSHAL_TIMEOUT) { return status; } timeout -= AJ_UNMARSHAL_TIMEOUT; status = AJ_OK; continue; } if (status == AJ_ERR_NO_MATCH) { // Ignore unknown messages status = AJ_OK; continue; } if (status != AJ_OK) { AJ_ErrPrintf(("AJ_StartClient(): status=%s\n", AJ_StatusText(status))); break; } switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_FIND_NAME): case AJ_REPLY_ID(AJ_METHOD_FIND_NAME_BY_TRANSPORT): if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_ErrPrintf(("AJ_StartClient(): AJ_METHOD_FIND_NAME: %s\n", msg.error)); status = AJ_ERR_FAILURE; } else { uint32_t disposition; AJ_UnmarshalArgs(&msg, "u", &disposition); if ((disposition != AJ_FIND_NAME_STARTED) && (disposition != AJ_FIND_NAME_ALREADY)) { AJ_ErrPrintf(("AJ_StartClient(): AJ_ERR_FAILURE\n")); status = AJ_ERR_FAILURE; } } break; case AJ_SIGNAL_FOUND_ADV_NAME: { AJ_Arg arg; AJ_UnmarshalArg(&msg, &arg); AJ_InfoPrintf(("FoundAdvertisedName(%s)\n", arg.val.v_string)); found = TRUE; status = AJ_BusJoinSession(bus, arg.val.v_string, port, opts); } break; case AJ_SIGNAL_ABOUT_ANNOUNCE: { uint16_t version, port; AJ_InfoPrintf(("AJ_StartClient(): AboutAnnounce from (%s)\n", msg.sender)); if (!found) { found = TRUE; AJ_UnmarshalArgs(&msg, "qq", &version, &port); status = AJ_BusJoinSession(bus, msg.sender, port, opts); if (serviceName != NULL) { strncpy(serviceName, msg.sender, AJ_MAX_NAME_SIZE); serviceName[AJ_MAX_NAME_SIZE] = '\0'; } if (status != AJ_OK) { AJ_ErrPrintf(("AJ_StartClient(): BusJoinSession failed (%s)\n", AJ_StatusText(status))); } } } break; case AJ_REPLY_ID(AJ_METHOD_JOIN_SESSION): { uint32_t replyCode; if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_ErrPrintf(("AJ_StartClient(): AJ_METHOD_JOIN_SESSION: %s\n", msg.error)); status = AJ_ERR_FAILURE; } else { status = AJ_UnmarshalArgs(&msg, "uu", &replyCode, sessionId); if (replyCode == AJ_JOINSESSION_REPLY_SUCCESS) { clientStarted = TRUE; } else { AJ_ErrPrintf(("AJ_StartClient(): AJ_METHOD_JOIN_SESSION reply (%d)\n", replyCode)); status = AJ_ERR_FAILURE; } } } break; case AJ_SIGNAL_SESSION_LOST_WITH_REASON: /* * Force a disconnect */ { uint32_t id, reason; AJ_UnmarshalArgs(&msg, "uu", &id, &reason); AJ_InfoPrintf(("Session lost. ID = %u, reason = %u", id, reason)); } AJ_ErrPrintf(("AJ_StartClient(): AJ_SIGNAL_SESSION_LOST_WITH_REASON: AJ_ERR_READ\n")); status = AJ_ERR_READ; break; default: /* * Pass to the built-in bus message handlers */ AJ_InfoPrintf(("AJ_StartClient(): AJ_BusHandleBusMessage()\n")); status = AJ_BusHandleBusMessage(&msg); break; } AJ_CloseMsg(&msg); } if (status != AJ_OK && !connected) { AJ_WarnPrintf(("AJ_StartClient(): Client disconnecting from bus: status=%s\n", AJ_StatusText(status))); AJ_Disconnect(bus); } return status; }
static AJ_Status AJ_Net_SendTo(AJ_IOBuffer* buf) { DWORD ret; DWORD tx = AJ_IO_BUF_AVAIL(buf); int numWrites = 0; AJ_InfoPrintf(("AJ_Net_SendTo(buf=0x%p)\n", buf)); assert(buf->direction == AJ_IO_BUF_TX); assert(NumMcastSocks > 0); if (tx > 0) { size_t i; // our router (hopefully) lives on one of the networks but we don't know which one. // send discovery requests to all of them. for (i = 0; i < NumMcastSocks; ++i) { SOCKET sock = McastSocks[i].sock; int family = McastSocks[i].family; if ((buf->flags & AJ_IO_BUF_AJ) && !McastSocks[i].is_mdns) { // try sending IPv6 multicast if (family == AF_INET6) { struct sockaddr_in6 sin6; memset(&sin6, 0, sizeof(struct sockaddr_in6)); sin6.sin6_family = AF_INET6; sin6.sin6_port = htons(AJ_UDP_PORT); inet_pton(AF_INET6, AJ_IPV6_MULTICAST_GROUP, &sin6.sin6_addr); ret = sendto(sock, buf->readPtr, tx, 0, (struct sockaddr*) &sin6, sizeof(struct sockaddr_in6)); if (ret == SOCKET_ERROR) { AJ_ErrPrintf(("AJ_Net_SendTo(): sendto() failed (IPV6). WSAGetLastError()=0x%x\n", WSAGetLastError())); } else { ++numWrites; } } // try sending IPv4 multicast if (family == AF_INET && McastSocks[i].has_mcast4) { struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(AJ_UDP_PORT); inet_pton(AF_INET, AJ_IPV4_MULTICAST_GROUP, &sin.sin_addr); ret = sendto(sock, buf->readPtr, tx, 0, (struct sockaddr*) &sin, sizeof(struct sockaddr_in)); if (ret == SOCKET_ERROR) { AJ_ErrPrintf(("AJ_Net_SendTo(): sendto() failed (IPV4). WSAGetLastError()=0x%x\n", WSAGetLastError())); } else { ++numWrites; } } // try sending IPv4 subnet broadcast if (family == AF_INET && McastSocks[i].v4_bcast.s_addr) { struct sockaddr_in bsin; memset(&bsin, 0, sizeof(bsin)); bsin.sin_family = AF_INET; bsin.sin_port = htons(AJ_UDP_PORT); bsin.sin_addr.s_addr = McastSocks[i].v4_bcast.s_addr; ret = sendto(sock, buf->readPtr, tx, 0, (struct sockaddr*) &bsin, sizeof(struct sockaddr_in)); if (ret == SOCKET_ERROR) { AJ_ErrPrintf(("AJ_Net_SendTo(): sendto() failed (bcast). WSAGetLastError()=0x%x\n", WSAGetLastError())); } else { ++numWrites; } } } if ((buf->flags & AJ_IO_BUF_MDNS) && McastSocks[i].is_mdns) { // Update the packet with receiver info for this socket if (RewriteSenderInfo(buf, ntohl(McastSocks[i].v4_addr.s_addr), McastSocks[i].recv_port) != AJ_OK) { AJ_WarnPrintf(("AJ_Net_SendTo(): RewriteSenderInfo failed.\n")); continue; } tx = AJ_IO_BUF_AVAIL(buf); // try sending IPv4 multicast if (family == AF_INET && McastSocks[i].has_mcast4) { struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(MDNS_UDP_PORT); inet_pton(AF_INET, MDNS_IPV4_MULTICAST_GROUP, &sin.sin_addr); ret = sendto(sock, buf->readPtr, tx, 0, (struct sockaddr*) &sin, sizeof(struct sockaddr_in)); if (ret == SOCKET_ERROR) { AJ_ErrPrintf(("AJ_Net_SendTo(): sendto() multicast failed (IPV4). WSAGetLastError()=0x%x\n", WSAGetLastError())); } else { ++numWrites; } } // try sending IPv4 subnet broadcast if (family == AF_INET && McastSocks[i].v4_bcast.s_addr) { struct sockaddr_in bsin; memset(&bsin, 0, sizeof(bsin)); bsin.sin_family = AF_INET; bsin.sin_port = htons(MDNS_UDP_PORT); bsin.sin_addr.s_addr = McastSocks[i].v4_bcast.s_addr; ret = sendto(sock, buf->readPtr, tx, 0, (struct sockaddr*) &bsin, sizeof(struct sockaddr_in)); if (ret == SOCKET_ERROR) { AJ_ErrPrintf(("AJ_Net_SendTo(): sendto() broadcast failed. WSAGetLastError()=0x%x\n", WSAGetLastError())); } else { ++numWrites; } } // try sending IPv6 multicast if (family == AF_INET6) { struct sockaddr_in6 sin6; memset(&sin6, 0, sizeof(struct sockaddr_in6)); sin6.sin6_family = AF_INET6; sin6.sin6_port = htons(MDNS_UDP_PORT); inet_pton(AF_INET6, MDNS_IPV6_MULTICAST_GROUP, &sin6.sin6_addr); ret = sendto(sock, buf->readPtr, tx, 0, (struct sockaddr*) &sin6, sizeof(struct sockaddr_in6)); if (ret == SOCKET_ERROR) { AJ_ErrPrintf(("AJ_Net_SendTo(): sendto() failed (IPV6). WSAGetLastError()=0x%x\n", WSAGetLastError())); } else { ++numWrites; } } } } if (numWrites == 0) { AJ_ErrPrintf(("AJ_Net_SendTo(): Did not sendto() at least one socket. status=AJ_ERR_WRITE\n")); return AJ_ERR_WRITE; } buf->readPtr += ret; } AJ_IO_BUF_RESET(buf); AJ_InfoPrintf(("AJ_Net_SendTo(): status=AJ_OK\n")); return AJ_OK; }
AJ_Status AJ_StartClient2(AJ_BusAttachment* bus, const char* daemonName, uint32_t timeout, uint8_t connected, const char* name, uint16_t port, uint32_t* sessionId, const AJ_SessionOpts* opts ) { AJ_Status status = AJ_OK; AJ_Time timer; AJ_Time unmarshalTimer; uint8_t foundName = FALSE; uint8_t clientStarted = FALSE; uint8_t initial = TRUE; AJ_InitTimer(&timer); while (TRUE) { if (AJ_GetElapsedTime(&timer, TRUE) > timeout) { return AJ_ERR_TIMEOUT; } if (!initial || !connected) { initial = FALSE; AJ_InfoPrintf(("Attempting to connect to bus\n")); status = AJ_Connect(bus, daemonName, CONNECT_TIMEOUT); if (status != AJ_OK) { AJ_WarnPrintf(("Failed to connect to bus sleeping for %d seconds\n", CONNECT_PAUSE / 1000)); AJ_Sleep(CONNECT_PAUSE); continue; } AJ_InfoPrintf(("AllJoyn client connected to bus\n")); } /* * Kick things off by finding the service names */ status = AJ_BusFindAdvertisedName(bus, name, AJ_BUS_START_FINDING); if (status == AJ_OK) { break; } AJ_WarnPrintf(("FindAdvertisedName failed\n")); AJ_Disconnect(bus); } *sessionId = 0; while (!clientStarted && (status == AJ_OK)) { AJ_Message msg; if (AJ_GetElapsedTime(&timer, TRUE) > timeout) { return AJ_ERR_TIMEOUT; } status = AJ_UnmarshalMsg(bus, &msg, UNMARSHAL_TIMEOUT); /* * TODO This is a temporary hack to work around buggy select imlpementations */ AJ_InitTimer(&unmarshalTimer); if (status == AJ_ERR_TIMEOUT && (AJ_GetElapsedTime(&unmarshalTimer, TRUE) < UNMARSHAL_TIMEOUT || !foundName)) { /* * Timeouts are expected until we find a name */ status = AJ_OK; continue; } if (status != AJ_OK) { break; } switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_FIND_NAME): case AJ_REPLY_ID(AJ_METHOD_FIND_NAME_BY_TRANSPORT): if (msg.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_FAILURE; } else { uint32_t disposition; AJ_UnmarshalArgs(&msg, "u", &disposition); if ((disposition != AJ_FIND_NAME_STARTED) && (disposition != AJ_FIND_NAME_ALREADY)) { status = AJ_ERR_FAILURE; } } break; case AJ_SIGNAL_FOUND_ADV_NAME: { AJ_Arg arg; AJ_UnmarshalArg(&msg, &arg); AJ_InfoPrintf(("FoundAdvertisedName(%s)\n", arg.val.v_string)); foundName = TRUE; status = AJ_BusJoinSession(bus, arg.val.v_string, port, opts); } break; case AJ_REPLY_ID(AJ_METHOD_JOIN_SESSION): { uint32_t replyCode; if (msg.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_FAILURE; } else { status = AJ_UnmarshalArgs(&msg, "uu", &replyCode, sessionId); if (replyCode == AJ_JOINSESSION_REPLY_SUCCESS) { clientStarted = TRUE; AJ_BusSetSignalRule2(bus, "NameOwnerChanged", "org.freedesktop.DBus", AJ_BUS_SIGNAL_ALLOW); } else { status = AJ_ERR_FAILURE; } } } break; case AJ_SIGNAL_SESSION_LOST: /* * Force a disconnect */ status = AJ_ERR_READ; break; default: /* * Pass to the built-in bus message handlers */ status = AJ_BusHandleBusMessage(&msg); break; } AJ_CloseMsg(&msg); } if (status != AJ_OK) { AJ_WarnPrintf(("AllJoyn disconnect bus status=%s\n", AJ_StatusText(status))); AJ_Disconnect(bus); } return status; }
int AJ_Main() { AJ_Status status = AJ_OK; AJ_BusAttachment bus; uint8_t connected = FALSE; uint32_t sessionId = 0; /* * One time initialization before calling any other AllJoyn APIs */ AJ_Initialize(); AJ_PrintXML(AppObjects); AJ_RegisterObjects(AppObjects, NULL); SetBusAuthPwdCallback(MyBusAuthPwdCB); while (TRUE) { AJ_Message msg; if (!connected) { status = AJ_StartService(&bus, NULL, CONNECT_TIMEOUT, FALSE, ServicePort, ServiceName, AJ_NAME_REQ_DO_NOT_QUEUE, NULL); if (status != AJ_OK) { continue; } AJ_InfoPrintf(("StartService returned AJ_OK\n")); AJ_InfoPrintf(("Connected to Daemon:%s\n", AJ_GetUniqueName(&bus))); connected = TRUE; #ifdef SECURE_OBJECT status = AJ_SetObjectFlags("/org/alljoyn/alljoyn_test", AJ_OBJ_FLAG_SECURE, 0); if (status != AJ_OK) { AJ_ErrPrintf(("Error calling AJ_SetObjectFlags.. [%s] \n", AJ_StatusText(status))); return -1; } #endif #if defined(SECURE_INTERFACE) || defined(SECURE_OBJECT) /* Register a callback for providing bus authentication password */ AJ_BusSetPasswordCallback(&bus, PasswordCallback); AJ_BusEnableSecurity(&bus, suites, numsuites); AJ_BusSetAuthListenerCallback(&bus, AuthListenerCallback); #endif /* Configure timeout for the link to the daemon bus */ AJ_SetBusLinkTimeout(&bus, 60); // 60 seconds } status = AJ_UnmarshalMsg(&bus, &msg, UNMARSHAL_TIMEOUT); if (AJ_ERR_TIMEOUT == status && AJ_ERR_LINK_TIMEOUT == AJ_BusLinkStateProc(&bus)) { status = AJ_ERR_READ; } if (status != AJ_OK) { if (status == AJ_ERR_TIMEOUT) { AppDoWork(); continue; } } if (status == AJ_OK) { switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_ADD_MATCH): if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_InfoPrintf(("Failed to add match\n")); status = AJ_ERR_FAILURE; } else { status = AJ_OK; } break; case AJ_METHOD_ACCEPT_SESSION: { uint16_t port; char* joiner; AJ_UnmarshalArgs(&msg, "qus", &port, &sessionId, &joiner); if (port == ServicePort) { status = AJ_BusReplyAcceptSession(&msg, TRUE); AJ_InfoPrintf(("Accepted session session_id=%u joiner=%s\n", sessionId, joiner)); } else { status = AJ_BusReplyAcceptSession(&msg, FALSE); AJ_InfoPrintf(("Accepted rejected session_id=%u joiner=%s\n", sessionId, joiner)); } } break; case APP_MY_PING: status = AppHandlePing(&msg); break; case APP_GET_PROP: status = AJ_BusPropGet(&msg, PropGetHandler, NULL); break; case APP_SET_PROP: status = AJ_BusPropSet(&msg, PropSetHandler, NULL); if (status == AJ_OK) { AJ_InfoPrintf(("Property successfully set to %d.\n", propVal)); } else { AJ_InfoPrintf(("Property set attempt unsuccessful. Status = 0x%04x.\n", status)); } break; case AJ_SIGNAL_SESSION_LOST_WITH_REASON: { uint32_t id, reason; AJ_UnmarshalArgs(&msg, "uu", &id, &reason); AJ_InfoPrintf(("Session lost. ID = %u, reason = %u", id, reason)); if (CancelAdvertiseName) { status = AJ_BusAdvertiseName(&bus, ServiceName, AJ_TRANSPORT_ANY, AJ_BUS_START_ADVERTISING, 0); } status = AJ_ERR_SESSION_LOST; } break; case AJ_SIGNAL_SESSION_JOINED: if (CancelAdvertiseName) { status = AJ_BusAdvertiseName(&bus, ServiceName, AJ_TRANSPORT_ANY, AJ_BUS_STOP_ADVERTISING, 0); } break; case AJ_REPLY_ID(AJ_METHOD_CANCEL_ADVERTISE): case AJ_REPLY_ID(AJ_METHOD_ADVERTISE_NAME): if (msg.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_FAILURE; } break; case APP_MY_SIGNAL: AJ_InfoPrintf(("Received my_signal\n")); status = AJ_OK; if (ReflectSignal) { AJ_Message out; AJ_MarshalSignal(&bus, &out, APP_MY_SIGNAL, msg.destination, msg.sessionId, 0, 0); AJ_MarshalArgs(&out, "a{ys}", 0, NULL); AJ_DeliverMsg(&out); AJ_CloseMsg(&out); } break; default: /* * Pass to the built-in bus message handlers */ status = AJ_BusHandleBusMessage(&msg); break; } // Any received packets indicates the link is active, so call to reinforce the bus link state AJ_NotifyLinkActive(); } /* * Unarshaled messages must be closed to free resources */ AJ_CloseMsg(&msg); if ((status == AJ_ERR_READ) || (status == AJ_ERR_LINK_DEAD)) { AJ_InfoPrintf(("AllJoyn disconnect\n")); AJ_InfoPrintf(("Disconnected from Daemon:%s\n", AJ_GetUniqueName(&bus))); AJ_Disconnect(&bus); connected = FALSE; /* * Sleep a little while before trying to reconnect */ AJ_Sleep(10 * 1000); } } AJ_WarnPrintf(("svclite EXIT %d\n", status)); return status; }
static AJ_Status Restart(void) { AJ_WarnPrintf(("Restart\n")); AJ_AboutSetShouldAnnounce(); return AJ_ERR_RESTART; }
AJ_Status AJ_HandleIntrospectRequest(const AJ_Message* msg, AJ_Message* reply) { AJ_Status status = AJ_OK; const AJ_Object* obj = objectLists[AJ_APP_ID_FLAG]; uint32_t children = 0; AJ_Object parent; WriteContext context; /* * Return an error if there are no local objects */ if (!obj) { return AJ_MarshalErrorMsg(msg, reply, AJ_ErrServiceUnknown); } /* * Find out which object we are introspecting. There are two possibilities: * * - The request has a complete object path to one of the application objects. * - The request has a path to a parent object of one or more application objects where the * parent itself is just a place-holder in the object hierarchy. */ for (; obj->path != NULL; ++obj) { if (strcmp(msg->objPath, obj->path) == 0) { break; } if (ChildPath(msg->objPath, obj->path, NULL)) { ++children; } } /* * If there was not a direct match but the requested node has children we create * a temporary AJ_Object for the parent and introspect that object. */ if ((obj->path == NULL) && children) { parent.flags = 0; parent.path = msg->objPath; parent.interfaces = NULL; obj = &parent; } /* * Skip objects that are hidden or disabled */ if (obj->path && !(obj->flags & (AJ_OBJ_FLAG_HIDDEN | AJ_OBJ_FLAG_DISABLED))) { /* * First pass computes the size of the XML string */ context.len = 0; status = GenXML(SizeXML, &context.len, obj, objectLists[1]); if (status != AJ_OK) { AJ_ErrPrintf(("AJ_HandleIntrospectRequest(): Failed to generate XML. status=%s", AJ_StatusText(status))); return status; } /* * Second pass marshals the XML */ AJ_InfoPrintf(("AJ_HandleIntrospectRequest() %d bytes of XML\n", context.len)); AJ_MarshalReplyMsg(msg, reply); /* * Do a partial delivery */ status = AJ_DeliverMsgPartial(reply, context.len + 5); /* * Marshal the string length */ if (status == AJ_OK) { status = AJ_MarshalRaw(reply, &context.len, 4); } if (status == AJ_OK) { uint8_t nul = 0; context.status = AJ_OK; context.reply = reply; GenXML(WriteXML, &context, obj, objectLists[1]); status = context.status; if (status == AJ_OK) { /* * Marshal the terminating NUL */ status = AJ_MarshalRaw(reply, &nul, 1); } } } else { /* * Return a ServiceUnknown error response */ AJ_WarnPrintf(("AJ_HandleIntrospectRequest() NO MATCH for %s\n", msg->objPath)); AJ_MarshalErrorMsg(msg, reply, AJ_ErrServiceUnknown); } return status; }
static AJ_Status DoConnectWifi(AJOBS_Info* connectInfo) { AJ_Status status = AJ_OK; AJ_WiFiSecurityType secType = AJ_WIFI_SECURITY_NONE; AJ_WiFiCipherType cipherType = AJ_WIFI_CIPHER_NONE; AJOBS_AuthType fallback = AJOBS_AUTH_TYPE_OPEN; AJOBS_AuthType fallbackUntil = AJOBS_AUTH_TYPE_OPEN; uint8_t retries = 0; AJ_WiFiConnectState wifiConnectState; AJ_InfoPrintf(("Attempting to connect to %s with passcode=%s and auth=%d\n", connectInfo->ssid, connectInfo->pc, connectInfo->authType)); switch (connectInfo->authType) { case AJOBS_AUTH_TYPE_ANY: if (strlen(connectInfo->pc) == 0) { break; } fallback = AJOBS_AUTH_TYPE_WPA2_CCMP; fallbackUntil = AJOBS_AUTH_TYPE_OPEN; break; case AJOBS_AUTH_TYPE_WPA_AUTO: if (strlen(connectInfo->pc) == 0) { break; } fallback = AJOBS_AUTH_TYPE_WPA_CCMP; fallbackUntil = AJOBS_AUTH_TYPE_WPA_TKIP; break; case AJOBS_AUTH_TYPE_WPA2_AUTO: if (strlen(connectInfo->pc) == 0) { break; } fallback = AJOBS_AUTH_TYPE_WPA2_CCMP; fallbackUntil = AJOBS_AUTH_TYPE_WPA2_TKIP; break; default: fallback = connectInfo->authType; } secType = GetSecType(fallback); cipherType = GetCipherType(fallback); AJ_InfoPrintf(("Trying to connect with auth=%d (secType=%d, cipherType=%d)\n", fallback, secType, cipherType)); while (1) { if (connectInfo->state == AJOBS_STATE_CONFIGURED_NOT_VALIDATED) { connectInfo->state = AJOBS_STATE_CONFIGURED_VALIDATING; } uint8_t raw[(AJOBS_PASSCODE_MAX_LENGTH / 2) + 1]; char* password = connectInfo->pc; if (AJ_WIFI_CIPHER_WEP != cipherType) { size_t hexLen = strlen(connectInfo->pc); AJ_HexToRaw(connectInfo->pc, hexLen, raw, (AJOBS_PASSCODE_MAX_LENGTH / 2) + 1); password = (char*)raw; password[hexLen / 2] = '\0'; } status = AJ_ConnectWiFi(connectInfo->ssid, secType, cipherType, password); AJ_InfoPrintf(("AJ_ConnectWifi returned %s\n", AJ_StatusText(status))); wifiConnectState = AJ_GetWifiConnectState(); // Set last error and state if ((status == AJ_OK) /* (wifiConnectState == AJ_WIFI_CONNECT_OK)*/) { obLastError.code = AJOBS_STATE_LAST_ERROR_VALIDATED; obLastError.message[0] = '\0'; obState = AJOBS_STATE_CONFIGURED_VALIDATED; connectInfo->authType = fallback; } else if ((status == AJ_ERR_CONNECT) /* (wifiConnectState == AJ_WIFI_CONNECT_FAILED)*/) { obLastError.code = AJOBS_STATE_LAST_ERROR_UNREACHABLE; strncpy(obLastError.message, "Network unreachable!", AJOBS_ERROR_MESSAGE_LEN); if (connectInfo->state == AJOBS_STATE_CONFIGURED_VALIDATED || connectInfo->state == AJOBS_STATE_CONFIGURED_RETRY) { obState = AJOBS_STATE_CONFIGURED_RETRY; } else { obState = AJOBS_STATE_CONFIGURED_ERROR; } } else if ((status == AJ_ERR_SECURITY) /* (wifiConnectState == AJ_WIFI_AUTH_FAILED)*/) { obLastError.code = AJOBS_STATE_LAST_ERROR_UNAUTHORIZED; strncpy(obLastError.message, "Authorization failed!", AJOBS_ERROR_MESSAGE_LEN); if (connectInfo->state == AJOBS_STATE_CONFIGURED_VALIDATED || connectInfo->state == AJOBS_STATE_CONFIGURED_RETRY) { obState = AJOBS_STATE_CONFIGURED_RETRY; } else { obState = AJOBS_STATE_CONFIGURED_ERROR; } } else if (status == AJ_ERR_DRIVER) { obLastError.code = AJOBS_STATE_LAST_ERROR_ERROR_MESSAGE; strncpy(obLastError.message, "Driver error", AJOBS_ERROR_MESSAGE_LEN); obState = AJOBS_STATE_CONFIGURED_ERROR; } else if (status == AJ_ERR_DHCP) { obLastError.code = AJOBS_STATE_LAST_ERROR_ERROR_MESSAGE; strncpy(obLastError.message, "Failed to establish IP!", AJOBS_ERROR_MESSAGE_LEN); if (connectInfo->state == AJOBS_STATE_CONFIGURED_VALIDATED || connectInfo->state == AJOBS_STATE_CONFIGURED_RETRY) { obState = AJOBS_STATE_CONFIGURED_RETRY; } else { obState = AJOBS_STATE_CONFIGURED_ERROR; } } else { obLastError.code = AJOBS_STATE_LAST_ERROR_ERROR_MESSAGE; strncpy(obLastError.message, "Failed to connect! Unexpected error", AJOBS_ERROR_MESSAGE_LEN); obState = AJOBS_STATE_CONFIGURED_ERROR; } if (obState == AJOBS_STATE_CONFIGURED_VALIDATED) { break; } AJ_WarnPrintf(("Warning - DoConnectWifi wifiConnectState = %s\n", AJ_WiFiConnectStateText(wifiConnectState))); AJ_WarnPrintf(("Last error set to \"%s\" (code=%d)\n", obLastError.message, obLastError.code)); if (obState == AJOBS_STATE_CONFIGURED_ERROR || obState == AJOBS_STATE_CONFIGURED_RETRY) { if (retries++ >= obSettings->AJOBS_MAX_RETRIES) { if (obState == AJOBS_STATE_CONFIGURED_ERROR && connectInfo->state == AJOBS_STATE_CONFIGURED_VALIDATING) { if (connectInfo->authType < 0 && fallback > fallbackUntil) { obLastError.code = AJOBS_STATE_LAST_ERROR_UNSUPPORTED_PROTOCOL; strncpy(obLastError.message, "Unsupported protocol", AJOBS_ERROR_MESSAGE_LEN); fallback--; // Try next authentication protocol secType = GetSecType(fallback); cipherType = GetCipherType(fallback); retries = 0; AJ_InfoPrintf(("Trying to connect with fallback auth=%d (secType=%d, cipherType=%d)\n", fallback, secType, cipherType)); continue; } } break; } AJ_InfoPrintf(("Retry number %d out of %d\n", retries, obSettings->AJOBS_MAX_RETRIES)); } } connectInfo->state = obState; status = (*obWriteInfo)(connectInfo); return status; }
AJ_Status AJ_StartService2(AJ_BusAttachment* bus, const char* daemonName, uint32_t timeout, uint8_t connected, uint16_t port, const char* name, uint32_t flags, const AJ_SessionOpts* opts ) { AJ_Status status; AJ_Time timer; uint8_t serviceStarted = FALSE; uint8_t initial = TRUE; AJ_InitTimer(&timer); while (TRUE) { if (AJ_GetElapsedTime(&timer, TRUE) > timeout) { return AJ_ERR_TIMEOUT; } if (!initial || !connected) { initial = FALSE; AJ_InfoPrintf(("Attempting to connect to bus\n")); status = AJ_Connect(bus, daemonName, CONNECT_TIMEOUT); if (status != AJ_OK) { AJ_WarnPrintf(("Failed to connect to bus sleeping for %d seconds\n", CONNECT_PAUSE / 1000)); AJ_Sleep(CONNECT_PAUSE); continue; } AJ_InfoPrintf(("AllJoyn service connected to bus\n")); } /* * Kick things off by binding a session port */ status = AJ_BusBindSessionPort(bus, port, opts); if (status == AJ_OK) { break; } AJ_ErrPrintf(("Failed to send bind session port message\n")); AJ_Disconnect(bus); } while (!serviceStarted && (status == AJ_OK)) { AJ_Message msg; AJ_GetElapsedTime(&timer, TRUE); status = AJ_UnmarshalMsg(bus, &msg, UNMARSHAL_TIMEOUT); /* * TODO This is a temporary hack to work around buggy select imlpementations */ if (status == AJ_ERR_TIMEOUT) { if (AJ_GetElapsedTime(&timer, TRUE) < UNMARSHAL_TIMEOUT) { AJ_WarnPrintf(("Spurious timeout error - continuing\n")); status = AJ_OK; continue; } } if (status != AJ_OK) { break; } switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_BIND_SESSION_PORT): if (msg.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_FAILURE; } else { status = AJ_BusRequestName(bus, name, flags); } break; case AJ_REPLY_ID(AJ_METHOD_REQUEST_NAME): if (msg.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_FAILURE; } else { status = AJ_BusAdvertiseName(bus, name, AJ_TRANSPORT_ANY, AJ_BUS_START_ADVERTISING); } break; case AJ_REPLY_ID(AJ_METHOD_ADVERTISE_NAME): if (msg.hdr->msgType == AJ_MSG_ERROR) { status = AJ_ERR_FAILURE; } else { serviceStarted = TRUE; AJ_BusSetSignalRule2(bus, "NameOwnerChanged", "org.freedesktop.DBus", AJ_BUS_SIGNAL_ALLOW); } break; default: /* * Pass to the built-in bus message handlers */ status = AJ_BusHandleBusMessage(&msg); break; } AJ_CloseMsg(&msg); } if (status != AJ_OK) { AJ_WarnPrintf(("AllJoyn disconnect bus status=%s\n", AJ_StatusText(status))); AJ_Disconnect(bus); } return status; }
AJ_Status AJ_StartClient(AJ_BusAttachment* bus, const char* daemonName, uint32_t timeout, uint8_t connected, const char* name, uint16_t port, uint32_t* sessionId, const AJ_SessionOpts* opts) { AJ_Status status = AJ_OK; AJ_Time timer; uint8_t foundName = FALSE; uint8_t clientStarted = FALSE; uint32_t elapsed = 0; AJ_InfoPrintf(("AJ_StartClient(bus=0x%p, daemonName=\"%s\", timeout=%d., connected=%d., name=\"%s\", port=%d., sessionId=0x%p, opts=0x%p)\n", bus, daemonName, timeout, connected, name, port, sessionId, opts)); AJ_InitTimer(&timer); while (elapsed < timeout) { if (!connected) { AJ_InfoPrintf(("AJ_StartClient(): AJ_FindBusAndConnect()\n")); status = AJ_FindBusAndConnect(bus, daemonName, AJ_CONNECT_TIMEOUT); elapsed = AJ_GetElapsedTime(&timer, TRUE); if (status != AJ_OK) { elapsed += AJ_CONNECT_PAUSE; if (elapsed > timeout) { break; } AJ_WarnPrintf(("Failed to connect to bus sleeping for %d seconds\n", AJ_CONNECT_PAUSE / 1000)); AJ_Sleep(AJ_CONNECT_PAUSE); continue; } AJ_InfoPrintf(("AllJoyn client connected to bus\n")); } /* * Kick things off by finding the service names */ AJ_InfoPrintf(("AJ_StartClient(): AJ_BusFindAdvertisedName()\n")); status = AJ_BusFindAdvertisedName(bus, name, AJ_BUS_START_FINDING); if (status == AJ_OK) { break; } if (!connected) { AJ_WarnPrintf(("AjStartClient2(): AJ_Disconnect(): status=%s.\n", AJ_StatusText(status))); AJ_Disconnect(bus); } } if (elapsed > timeout) { return AJ_ERR_TIMEOUT; } timeout -= elapsed; *sessionId = 0; while (!clientStarted && (status == AJ_OK)) { AJ_Message msg; status = AJ_UnmarshalMsg(bus, &msg, AJ_UNMARSHAL_TIMEOUT); if ((status == AJ_ERR_TIMEOUT) && !foundName) { /* * Timeouts are expected until we find a name */ if (timeout < AJ_UNMARSHAL_TIMEOUT) { return status; } timeout -= AJ_UNMARSHAL_TIMEOUT; status = AJ_OK; continue; } if (status != AJ_OK) { AJ_ErrPrintf(("AJ_StartClient(): status=%s\n", AJ_StatusText(status))); break; } switch (msg.msgId) { case AJ_REPLY_ID(AJ_METHOD_FIND_NAME): case AJ_REPLY_ID(AJ_METHOD_FIND_NAME_BY_TRANSPORT): if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_ErrPrintf(("AJ_StartClient(): AJ_METHOD_FIND_NAME: %s\n", msg.error)); status = AJ_ERR_FAILURE; } else { uint32_t disposition; AJ_UnmarshalArgs(&msg, "u", &disposition); if ((disposition != AJ_FIND_NAME_STARTED) && (disposition != AJ_FIND_NAME_ALREADY)) { AJ_ErrPrintf(("AJ_StartClient(): AJ_ERR_FAILURE\n")); status = AJ_ERR_FAILURE; } } break; case AJ_SIGNAL_FOUND_ADV_NAME: { AJ_Arg arg; AJ_UnmarshalArg(&msg, &arg); AJ_InfoPrintf(("FoundAdvertisedName(%s)\n", arg.val.v_string)); foundName = TRUE; status = AJ_BusJoinSession(bus, arg.val.v_string, port, opts); } break; case AJ_REPLY_ID(AJ_METHOD_JOIN_SESSION): { uint32_t replyCode; if (msg.hdr->msgType == AJ_MSG_ERROR) { AJ_ErrPrintf(("AJ_StartClient(): AJ_METHOD_JOIN_SESSION: %s\n", msg.error)); status = AJ_ERR_FAILURE; } else { status = AJ_UnmarshalArgs(&msg, "uu", &replyCode, sessionId); if (replyCode == AJ_JOINSESSION_REPLY_SUCCESS) { clientStarted = TRUE; } else { AJ_ErrPrintf(("AJ_StartClient(): AJ_ERR_FAILURE\n")); status = AJ_ERR_FAILURE; } } } break; case AJ_SIGNAL_SESSION_LOST_WITH_REASON: /* * Force a disconnect */ { uint32_t id, reason; AJ_UnmarshalArgs(&msg, "uu", &id, &reason); AJ_InfoPrintf(("Session lost. ID = %u, reason = %u", id, reason)); } AJ_ErrPrintf(("AJ_StartClient(): AJ_SIGNAL_SESSION_LOST_WITH_REASON: AJ_ERR_READ\n")); status = AJ_ERR_READ; break; default: /* * Pass to the built-in bus message handlers */ AJ_InfoPrintf(("AJ_StartClient(): AJ_BusHandleBusMessage()\n")); status = AJ_BusHandleBusMessage(&msg); break; } AJ_CloseMsg(&msg); } if (status != AJ_OK) { AJ_WarnPrintf(("AJ_StartClient(): AJ_Disconnect(): status=%s\n", AJ_StatusText(status))); AJ_Disconnect(bus); } return status; }
AJ_EXPORT AJ_Status AJ_WSL_NET_connect(const char* SSID, const char* passphrase, WSL_NET_AUTH_MODE auth, WSL_NET_CRYPTO_TYPE crypto, uint8_t softAP) { AJ_Status status; wsl_scan_list* list; list = (wsl_scan_list*)AJ_WSL_GetScanList(); WSL_ClearScanList(list); AJ_WSL_NET_SetPowerMode(2); uint8_t bss_mac[6]; // Open auth does not require you to explicitly set the BSSID so this secondary scan is not needed if (!softAP) { if (auth != WSL_NET_AUTH_NONE) { // Do a scan of just the SSID you want AJ_WSL_SetProbedSSID(SSID, 1); { AJ_BufList* start_scan; uint8_t found = 0; int i; AJ_WSL_NET_set_scan_params(); while (!found) { wsl_work_item* item; AJ_InfoPrintf(("AJ_WSL_NET_scan(): START_SCAN\n")); start_scan = AJ_BufListCreate(); AJ_WSL_SetProbedSSID(SSID, 1); AJ_WSL_NET_set_scan_params(); AJ_WSL_NET_BSS_FILTER(6); WSL_MarshalPacket(start_scan, WSL_START_SCAN, 0, 0, 0, 0, 0, 0, 0, 0); WMI_MarshalHeader(start_scan, 1, 1); AJ_WSL_WMI_PadPayload(start_scan); //AJ_BufListPrintDumpContinuous(start_scan); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_SCAN), AJ_WSL_HTC_DATA_ENDPOINT1, start_scan); status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_SCAN), &item); AJ_WSL_WMI_FreeWorkItem(item); // Get the new list (just of the SSID provided in the connect command) AJ_WSL_NET_scan_stop(); list = (wsl_scan_list*)AJ_WSL_GetScanList(); if (list->size == 0) { AJ_AlwaysPrintf(("Could not find access point %s\n", SSID)); WSL_ClearScanList(list); AJ_Sleep(AJ_WSL_CONNECT_WAIT); continue; } WSL_PrintScanSorted(); // Find the SSID you want to connect to in the second scan list for (i = 0; i < list->size; i++) { if (0 == strcmp(list->list[i].ssid, SSID)) { memcpy(&bss_mac, list->list[i].bssid, 6); found = 1; break; } } WSL_ClearScanList(list); } } } } { AJ_BufList* connect; AJ_BufList* connectOut; static const uint8_t zero_mac[6] = { 0, 0, 0, 0, 0, 0 }; uint8_t connect_mac[6]; wsl_work_item* item = NULL; uint8_t found = 0; connect = AJ_BufListCreate(); /* Three different ways connect can be called. * 1. SoftAP: The devices mac is fetched and used * 2. Using Auth: The SSID's mac is found and used * 3. Open auth: A zero'ed mac is used */ if (softAP) { WSL_MarshalPacket(connect, WSL_SET_SOFT_AP, 0, 0x04, 0x01, auth, crypto, 0x00, crypto, 0x00, strlen(SSID), SSID, 0x0, getDeviceMac(), 0x0044, 0x0000); WMI_MarshalHeader(connect, 1, 1); } else if ((auth != WSL_NET_AUTH_NONE) && (crypto != WSL_NET_CRYPTO_WEP)) { WSL_MarshalPacket(connect, WSL_CONNECT, 0, 0x01, 0x01, auth, crypto, 0x00, crypto, 0x00, strlen(SSID), SSID, 0x0, &bss_mac, 0x0044, 0x0000); WMI_MarshalHeader(connect, 1, 1); } else { // if the auth mode is open, use zero_mac, and set flags to zero WSL_MarshalPacket(connect, WSL_CONNECT, 0, 0x01, 0x01, auth, crypto, 0x00, crypto, 0x00, strlen(SSID), SSID, 0x0, &zero_mac, 0x0000, 0x0000); WMI_MarshalHeader(connect, 1, 1); } AJ_InfoPrintf(("AJ_WSL_NET_connect(): CONNECT\n")); AJ_WSL_WMI_PadPayload(connect); //AJ_BufListPrintDumpContinuous(connect); connectOut = AJ_BufListCreateCopy(connect); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_CONNECT), AJ_WSL_HTC_DATA_ENDPOINT1, connectOut); if (softAP) { AJ_AlwaysPrintf(("Waiting for a connection to the softAP %s\n", SSID)); memcpy(&connect_mac, (uint8_t*)getDeviceMac(), sizeof(connect_mac)); while (WSL_MacsAreEqual((uint8_t*)&connect_mac, (uint8_t*)getDeviceMac()) == TRUE) { status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_CONNECT), &item); if (item) { if (item->itemType == WSL_NET_CONNECT) { AJ_InfoPrintf(("AJ_WSL_ip6config(): WORK ITEM RECEIVED\n")); uint16_t WMIEvent; uint32_t toss; uint16_t channel; WMI_Unmarshal(item->node->buffer, "quqM", &WMIEvent, &toss, &channel, &connect_mac); } else { AJ_WarnPrintf(("AJ_WSL_NET_connect(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); found = 1; } } } else { status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_CONNECT), &item); AJ_WSL_WMI_FreeWorkItem(item); } AJ_BufListFree(connect, 1); return status; } }
static const char* DescriptionLookup(uint32_t descId, const char* lang) { const char* actualLanguage; int8_t langIndex = AJSVC_PropertyStore_GetLanguageIndex(lang); char deviceName[DEVICE_NAME_VALUE_LENGTH] = { '\0' }; uint8_t i; const char* deviceNamePerLanguage; AJ_InfoPrintf(("Looking up description for o:%u i:%u m:%u a:%u\n", (descId >> 24) & 0xFF, (descId >> 16) & 0xFF, (descId >> 8) & 0xFF, (descId >> 0) & 0xFF)); if (langIndex != AJSVC_PROPERTY_STORE_ERROR_LANGUAGE_INDEX) { actualLanguage = AJSVC_PropertyStore_GetLanguageName(langIndex); AJ_InfoPrintf((" language=%s\n", actualLanguage)); deviceNamePerLanguage = AJSVC_PropertyStore_GetValueForLang(AJSVC_PROPERTY_STORE_DEVICE_NAME, langIndex); if (deviceNamePerLanguage == NULL) { deviceNamePerLanguage = AJSVC_PropertyStore_GetValueForLang(AJSVC_PROPERTY_STORE_DEVICE_NAME, AJSVC_PropertyStore_GetCurrentDefaultLanguageIndex()); if (deviceNamePerLanguage == NULL) { AJ_ErrPrintf(("DeviceName for language=%s does not exist!\n", actualLanguage)); } } if (deviceNamePerLanguage != NULL) { strncpy(deviceName, deviceNamePerLanguage, DEVICE_NAME_VALUE_LENGTH); } for (i = 0; i < DEVICE_NAME_VALUE_LENGTH; i++) { // Replace any illegal/escaped XML characters with '_' if (deviceName[i] == '>' || deviceName[i] == '<' || deviceName[i] == '"' || deviceName[i] == '\'' || deviceName[i] == '&') { deviceName[i] = '_'; } } switch (descId) { case (EVENTSANDACTIONS_OBJECT_DESC): #ifdef _WIN32 _snprintf(description, DESCRIPTION_LENGTH, "%s Events and Actions [%s]", deviceName, actualLanguage); #else snprintf(description, DESCRIPTION_LENGTH, "%s Events and Actions [%s]", deviceName, actualLanguage); #endif return description; case (EVENTS_INTERFACE_DESC): #ifdef _WIN32 _snprintf(description, DESCRIPTION_LENGTH, "%s Events [%s]", deviceName, actualLanguage); #else snprintf(description, DESCRIPTION_LENGTH, "%s Events [%s]", deviceName, actualLanguage); #endif return description; case (EVENTS_TEMPERATURE80FREACHED_SLS_DESC): return "Triggerred when extreme temperature of 80F is reached while heating"; case (EVENTS_TEMPERATURE60FREACHED_SLS_DESC): return "Triggerred when extreme temperature of 60F is reached while cooling"; case (EVENTS_TURNEDOFF_SLS_DESC): return "Triggerred when the AC is turned OFF"; case (EVENTS_TURNEDON_SLS_DESC): return "Triggerred when the AC is turned ON"; case (ACTIONS_INTERFACE_DESC): #ifdef _WIN32 _snprintf(description, DESCRIPTION_LENGTH, "%s Actions [%s]", deviceName, actualLanguage); #else snprintf(description, DESCRIPTION_LENGTH, "%s Actions [%s]", deviceName, actualLanguage); #endif return description; case (ACTIONS_SETMODETOAUTO_DESC): return "Set AC mode to Auto"; case (ACTIONS_SETMODETOCOOL_DESC): return "Set AC mode to Cool"; case (ACTIONS_SETMODETOHEAT_DESC): return "Set AC mode to Heat"; case (ACTIONS_SETMODETOFAN_DESC): return "Set AC mode to Fan"; case (ACTIONS_SETMODETOOFF_DESC): return "Set AC mode to Off"; default: return NULL; } } AJ_WarnPrintf(("\nError: Unsupported language=%s\n", lang == NULL ? "NULL" : lang)); return NULL; }