[ENROLLEE] Tizen enrollee sample application build using scons command
[platform/upstream/iotivity.git] / service / easy-setup / mediator / csdk / src / wifi_provisioning.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 // NOTE : Keeping Wifi provisioning in this file to have adaptability while doing OOPs refactoring
22
23 #include "provisioning.h"
24
25 //Standard includes
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <signal.h>
30 #include <unistd.h>
31 #include <pthread.h>
32
33 //EasySetup include files
34 #include "ocpayload.h"
35 #include "escommon.h"
36
37 // External includes
38 #include "logger.h"
39
40 #define ES_WIFI_PROV_TAG "ES_WIFI_PROVISIONING"
41
42 static const char * UNICAST_PROV_STATUS_QUERY = "coap://%s:%d%s";
43
44 OCStackApplicationResult GetProvisioningStatusResponse(void* /*ctx*/,
45                                                         OCDoHandle /*handle*/,
46                                                         OCClientResponse *clientResponse) {
47
48
49     // If user stopped the process then return from this function;
50     if (IsSetupStopped()) {
51         ErrorCallback(DEVICE_NOT_PROVISIONED);
52         ClearMemory();
53         return OC_STACK_DELETE_TRANSACTION;
54     }
55
56     if (!ValidateEnrolleResponse(clientResponse)) {
57         ErrorCallback(DEVICE_NOT_PROVISIONED);
58         ClearMemory();
59         return OC_STACK_DELETE_TRANSACTION;
60     }
61
62     OCRepPayload *input = (OCRepPayload * )(clientResponse->payload);
63
64     char query[OIC_STRING_MAX_VALUE] =
65             {'\0'};
66     char resURI[MAX_URI_LENGTH] =
67             {'\0'};
68
69     OIC_LOG_V(DEBUG, ES_WIFI_PROV_TAG, "resUri = %s", input->uri);
70
71     strncpy(resURI, input->uri, sizeof(resURI) - 1);
72
73
74 #ifdef REMOTE_ARDUINO_ENROLEE
75     //Arduino Enrollee needs mediator application provide IP and port55555 which is specific
76     // to Arduino WiFi enrollee
77     // REMOTE_ARDUINO_ENROLEE has to be defined if Mediator is being tested with Arduino
78     snprintf(query, sizeof(query), UNICAST_PROV_STATUS_QUERY, clientResponse->addr->addr, IP_PORT,
79             resURI);
80 #else
81     snprintf(query, sizeof(query), UNICAST_PROV_STATUS_QUERY, clientResponse->addr->addr,
82             clientResponse->addr->port,
83             resURI);
84 #endif
85
86
87     if (ProvisionEnrollee(OC_HIGH_QOS, query, OC_RSRVD_ES_URI_PROV, clientResponse->addr, 0)
88         != OC_STACK_OK) {
89         OIC_LOG(INFO, ES_WIFI_PROV_TAG, "GetProvisioningStatusResponse received NULL clientResponse");
90
91         ErrorCallback(DEVICE_NOT_PROVISIONED);
92         ClearMemory();
93         return OC_STACK_DELETE_TRANSACTION;
94     }
95
96     return OC_STACK_KEEP_TRANSACTION;
97
98 }
99
100 OCStackResult GetProvisioningStatus(OCQualityOfService qos, const char *query,
101                                     const OCDevAddr *destination) {
102     OCStackResult ret = OC_STACK_ERROR;
103     OCHeaderOption options[MAX_HEADER_OPTIONS];
104
105     OIC_LOG_V(INFO, ES_WIFI_PROV_TAG, "\n\nExecuting %s", __func__);
106
107     uint8_t option0[] =
108             {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
109     uint8_t option1[] =
110             {11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
111     memset(options, 0, sizeof(OCHeaderOption) * MAX_HEADER_OPTIONS);
112     options[0].protocolID = OC_COAP_ID;
113     options[0].optionID = 2048;
114     memcpy(options[0].optionData, option0, sizeof(option0));
115     options[0].optionLength = 10;
116     options[1].protocolID = OC_COAP_ID;
117     options[1].optionID = 3000;
118     memcpy(options[1].optionData, option1, sizeof(option1));
119     options[1].optionLength = 10;
120
121     ret = InvokeOCDoResource(query, OC_REST_GET, destination, qos,
122                              GetProvisioningStatusResponse, NULL, options, 2);
123     return ret;
124 }
125
126
127 // This is a function called back when a device is discovered
128 OCStackApplicationResult FindProvisioningResourceResponse(void* /*ctx*/,
129                                                             OCDoHandle /*handle*/,
130                                                             OCClientResponse *clientResponse) {
131
132     OIC_LOG_V(INFO, ES_WIFI_PROV_TAG, "Entering FindProvisioningResourceResponse %s",
133             clientResponse->devAddr.addr);
134
135     // If user stopped the process then return from this function;
136     if (IsSetupStopped()) {
137         ErrorCallback(DEVICE_NOT_PROVISIONED);
138         ClearMemory();
139         return OC_STACK_DELETE_TRANSACTION;
140     }
141
142     if (!ValidateFinddResourceResponse(clientResponse)) {
143         ErrorCallback(DEVICE_NOT_PROVISIONED);
144         return OC_STACK_DELETE_TRANSACTION;
145     }
146
147     char szQueryUri[64] = {0};
148
149     OCDiscoveryPayload *discoveryPayload = (OCDiscoveryPayload * )(clientResponse->payload);
150
151     OIC_LOG_V(DEBUG, ES_WIFI_PROV_TAG, "resUri = %s", discoveryPayload->resources->uri);
152
153 #ifdef REMOTE_ARDUINO_ENROLEE
154     //Arduino Enrollee needs mediator application provide IP and port55555 which is specific
155     // to Arduino WiFi enrollee
156     // REMOTE_ARDUINO_ENROLEE has to be defined if Mediator is being tested with Arduino
157     snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROV_STATUS_QUERY,
158              clientResponse->addr->addr,
159              IP_PORT,
160              discoveryPayload->resources->uri);
161 #else
162     snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROV_STATUS_QUERY,
163              clientResponse->devAddr.addr,
164              clientResponse->devAddr.port,
165              discoveryPayload->resources->uri);
166 #endif
167
168     OIC_LOG_V(DEBUG, ES_WIFI_PROV_TAG, "query before GetProvisioningStatus call = %s", szQueryUri);
169
170     if (GetProvisioningStatus(OC_HIGH_QOS, szQueryUri, &clientResponse->devAddr) != OC_STACK_OK) {
171         ErrorCallback(DEVICE_NOT_PROVISIONED);
172         return OC_STACK_DELETE_TRANSACTION;
173     }
174
175     return OC_STACK_KEEP_TRANSACTION;
176
177 }
178
179 bool ValidateEasySetupParams(const EnrolleeNWProvInfo *netInfo,
180                              OCProvisioningStatusCB provisioningStatusCallback) {
181
182     if (netInfo == NULL || strlen(netInfo->netAddressInfo.WIFI.ipAddress) == 0) {
183         OIC_LOG(ERROR, ES_WIFI_PROV_TAG, "Request URI is NULL");
184         return false;
185     }
186
187     if (provisioningStatusCallback == NULL) {
188         OIC_LOG(ERROR, ES_WIFI_PROV_TAG, "ProvisioningStatusCallback is NULL");
189         return false;
190     }
191
192     return true;
193
194 }
195
196
197