1d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt/*
2d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * Hotspot 2.0 - OMA DM client
36cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt * Copyright (c) 2013-2014, Qualcomm Atheros, Inc.
4d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt *
5d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * This software may be distributed under the terms of the BSD license.
6d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt * See README for more details.
7d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt */
8d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
9d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "includes.h"
10d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
11d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "common.h"
12d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "wpa_helpers.h"
13d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "xml-utils.h"
14d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "http-utils.h"
15d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "utils/browser.h"
16d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#include "osu_client.h"
17d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
18d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
19d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_SERVER_INITIATED_MGMT 1200
20d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_CLIENT_INITIATED_MGMT 1201
21d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_GENERIC_ALERT 1226
22d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
23d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt/* OMA-TS-SyncML-RepPro-V1_2_2 - 10. Response Status Codes */
24d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_OK 200
25d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_AUTH_ACCEPTED 212
26d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_CHUNKED_ITEM_ACCEPTED 213
27d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_NOT_EXECUTED 215
28d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_ATOMIC_ROLL_BACK_OK 216
29d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_NOT_MODIFIED 304
30d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_BAD_REQUEST 400
31d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_UNAUTHORIZED 401
32d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_FORBIDDEN 403
33d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_NOT_FOUND 404
34d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_COMMAND_NOT_ALLOWED 405
35d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_OPTIONAL_FEATURE_NOT_SUPPORTED 406
36d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_MISSING_CREDENTIALS 407
37d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_CONFLICT 409
38d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_GONE 410
39d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_INCOMPLETE_COMMAND 412
40d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_REQ_ENTITY_TOO_LARGE 413
41d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_URI_TOO_LONG 414
42d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_UNSUPPORTED_MEDIA_TYPE_OR_FORMAT 415
43d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_REQ_TOO_BIG 416
44d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_ALREADY_EXISTS 418
45d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_DEVICE_FULL 420
46d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_SIZE_MISMATCH 424
47d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_PERMISSION_DENIED 425
48d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_COMMAND_FAILED 500
49d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_COMMAND_NOT_IMPLEMENTED 501
50d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_RESP_ATOMIC_ROLL_BACK_FAILED 516
51d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
52d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_HS20_SUBSCRIPTION_CREATION \
53d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	"org.wi-fi.hotspot2dot0.SubscriptionCreation"
54d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_HS20_SUBSCRIPTION_PROVISIONING \
55d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	"org.wi-fi.hotspot2dot0.SubscriptionProvisioning"
56d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_HS20_SUBSCRIPTION_REMEDIATION \
57d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	"org.wi-fi.hotspot2dot0.SubscriptionRemediation"
58d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_HS20_POLICY_UPDATE \
59d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	"org.wi-fi.hotspot2dot0.PolicyUpdate"
60d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
61d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_URI_PPS "./Wi-Fi/org.wi-fi/PerProviderSubscription"
62d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#define DM_URI_LAUNCH_BROWSER \
63d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	"./DevDetail/Ext/org.wi-fi/Wi-Fi/Ops/launchBrowserToURI"
64d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
65d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
66d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void add_item(struct hs20_osu_client *ctx, xml_node_t *parent,
67d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		     const char *locuri, const char *data);
68d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
69d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
70d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic const char * int2str(int val)
71d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
72d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	static char buf[20];
73d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	snprintf(buf, sizeof(buf), "%d", val);
74d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return buf;
75d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
76d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
77d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
78d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic char * oma_dm_get_target_locuri(struct hs20_osu_client *ctx,
79d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				       xml_node_t *node)
80d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
81d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *locuri;
82d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *uri, *ret = NULL;
83d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
84d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	locuri = get_node(ctx->xml, node, "Item/Target/LocURI");
85d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (locuri == NULL)
86d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
87d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
88d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	uri = xml_node_get_text(ctx->xml, locuri);
89d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (uri)
90d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		ret = os_strdup(uri);
91d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_get_text_free(ctx->xml, uri);
92d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return ret;
93d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
94d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
95d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
96d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void oma_dm_add_locuri(struct hs20_osu_client *ctx, xml_node_t *parent,
97d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			      const char *element, const char *uri)
98d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
99d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *node;
100d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
101d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	node = xml_node_create(ctx->xml, parent, NULL, element);
102d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (node == NULL)
103d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return;
104d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create_text(ctx->xml, node, NULL, "LocURI", uri);
105d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
106d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
107d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
108d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic xml_node_t * oma_dm_build_hdr(struct hs20_osu_client *ctx,
109d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				     const char *url, int msgid)
110d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
111d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *syncml, *synchdr;
112d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_namespace_t *ns;
113d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
114d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	syncml = xml_node_create_root(ctx->xml, "SYNCML:SYNCML1.2", NULL, &ns,
115d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				      "SyncML");
116d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
117d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	synchdr = xml_node_create(ctx->xml, syncml, NULL, "SyncHdr");
118d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create_text(ctx->xml, synchdr, NULL, "VerDTD", "1.2");
119d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create_text(ctx->xml, synchdr, NULL, "VerProto", "DM/1.2");
120d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create_text(ctx->xml, synchdr, NULL, "SessionID", "1");
121d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create_text(ctx->xml, synchdr, NULL, "MsgID", int2str(msgid));
122d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
123d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	oma_dm_add_locuri(ctx, synchdr, "Target", url);
124d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	oma_dm_add_locuri(ctx, synchdr, "Source", ctx->devid);
125d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
126d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return syncml;
127d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
128d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
129d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
130d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void oma_dm_add_cmdid(struct hs20_osu_client *ctx, xml_node_t *parent,
131d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			     int cmdid)
132d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
133d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create_text(ctx->xml, parent, NULL, "CmdID", int2str(cmdid));
134d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
135d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
136d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
137d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic xml_node_t * add_alert(struct hs20_osu_client *ctx, xml_node_t *parent,
138d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			      int cmdid, int data)
139d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
140d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *node;
141d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
142d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	node = xml_node_create(ctx->xml, parent, NULL, "Alert");
143d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (node == NULL)
144d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
145d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	oma_dm_add_cmdid(ctx, node, cmdid);
146d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create_text(ctx->xml, node, NULL, "Data", int2str(data));
147d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
148d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return node;
149d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
150d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
151d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
152d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic xml_node_t * add_status(struct hs20_osu_client *ctx, xml_node_t *parent,
153d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			       int msgref, int cmdref, int cmdid,
154d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			       const char *cmd, int data, const char *targetref)
155d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
156d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *node;
157d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
158d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	node = xml_node_create(ctx->xml, parent, NULL, "Status");
159d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (node == NULL)
160d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
161d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	oma_dm_add_cmdid(ctx, node, cmdid);
162d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create_text(ctx->xml, node, NULL, "MsgRef", int2str(msgref));
163d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (cmdref)
164d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_create_text(ctx->xml, node, NULL, "CmdRef",
165d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				     int2str(cmdref));
166d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create_text(ctx->xml, node, NULL, "Cmd", cmd);
167d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create_text(ctx->xml, node, NULL, "Data", int2str(data));
168d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (targetref) {
169d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_create_text(ctx->xml, node, NULL, "TargetRef",
170d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				     targetref);
171d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
172d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
173d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return node;
174d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
175d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
176d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
177d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic xml_node_t * add_results(struct hs20_osu_client *ctx, xml_node_t *parent,
178d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				int msgref, int cmdref, int cmdid,
179d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				const char *locuri, const char *data)
180d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
181d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *node;
182d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
183d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	node = xml_node_create(ctx->xml, parent, NULL, "Results");
184d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (node == NULL)
185d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
186d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
187d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	oma_dm_add_cmdid(ctx, node, cmdid);
188d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create_text(ctx->xml, node, NULL, "MsgRef", int2str(msgref));
189d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create_text(ctx->xml, node, NULL, "CmdRef", int2str(cmdref));
190d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	add_item(ctx, node, locuri, data);
191d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
192d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return node;
193d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
194d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
195d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
196d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic char * mo_str(struct hs20_osu_client *ctx, const char *urn,
197d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		     const char *fname)
198d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
199d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *fnode, *tnds;
200d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *str;
201d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
202d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	fnode = node_from_file(ctx->xml, fname);
203d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (!fnode)
204d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
205d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	tnds = mo_to_tnds(ctx->xml, fnode, 0, urn, "syncml:dmddf1.2");
206d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_free(ctx->xml, fnode);
207d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (!tnds)
208d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
209d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
210d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	str = xml_node_to_str(ctx->xml, tnds);
211d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_free(ctx->xml, tnds);
212d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (str == NULL)
213d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
214d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "MgmtTree: %s", str);
215d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
216d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return str;
217d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
218d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
219d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
220d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void add_item(struct hs20_osu_client *ctx, xml_node_t *parent,
221d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		     const char *locuri, const char *data)
222d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
223d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *item, *node;
224d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
225d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	item = xml_node_create(ctx->xml, parent, NULL, "Item");
226d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	oma_dm_add_locuri(ctx, item, "Source", locuri);
227d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	node = xml_node_create(ctx->xml, item, NULL, "Meta");
228d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create_text_ns(ctx->xml, node, "syncml:metinf", "Format",
229d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				"Chr");
230d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create_text_ns(ctx->xml, node, "syncml:metinf", "Type",
231d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				"text/plain");
232d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create_text(ctx->xml, item, NULL, "Data", data);
233d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
234d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
235d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
236d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void add_replace_devinfo(struct hs20_osu_client *ctx, xml_node_t *parent,
237d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				int cmdid)
238d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
239d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *info, *child, *replace;
240d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	const char *name;
241d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char locuri[200], *txt;
242d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
243d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	info = node_from_file(ctx->xml, "devinfo.xml");
244d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (info == NULL) {
245d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Could not read devinfo.xml");
246d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return;
247d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
248d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
249d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	replace = xml_node_create(ctx->xml, parent, NULL, "Replace");
250d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (replace == NULL) {
251d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_free(ctx->xml, info);
252d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return;
253d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
254d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	oma_dm_add_cmdid(ctx, replace, cmdid);
255d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
256d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_for_each_child(ctx->xml, child, info) {
257d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_for_each_check(ctx->xml, child);
258d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		name = xml_node_get_localname(ctx->xml, child);
259d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_snprintf(locuri, sizeof(locuri), "./DevInfo/%s", name);
260d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		txt = xml_node_get_text(ctx->xml, child);
261d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (txt) {
262d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			add_item(ctx, replace, locuri, txt);
263d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			xml_node_get_text_free(ctx->xml, txt);
264d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
265d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
266d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
267d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_free(ctx->xml, info);
268d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
269d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
270d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
271d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic void oma_dm_add_hs20_generic_alert(struct hs20_osu_client *ctx,
272d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					  xml_node_t *syncbody,
273d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					  int cmdid, const char *oper,
274d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					  const char *data)
275d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
276d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *node, *item;
277d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char buf[200];
278d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
279d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	node = add_alert(ctx, syncbody, cmdid, DM_GENERIC_ALERT);
280d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
281d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	item = xml_node_create(ctx->xml, node, NULL, "Item");
282d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	oma_dm_add_locuri(ctx, item, "Source", DM_URI_PPS);
283d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	node = xml_node_create(ctx->xml, item, NULL, "Meta");
284d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	snprintf(buf, sizeof(buf), "Reversed-Domain-Name: %s", oper);
285d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create_text_ns(ctx->xml, node, "syncml:metinf", "Type", buf);
286d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create_text_ns(ctx->xml, node, "syncml:metinf", "Format",
287d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				"xml");
288d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create_text(ctx->xml, item, NULL, "Data", data);
289d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
290d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
291d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
292d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic xml_node_t * build_oma_dm_1(struct hs20_osu_client *ctx,
293d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				   const char *url, int msgid, const char *oper)
294d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
295d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *syncml, *syncbody;
296d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *str;
297d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int cmdid = 0;
298d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
299d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	syncml = oma_dm_build_hdr(ctx, url, msgid);
300d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (syncml == NULL)
301d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
302d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
303d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	syncbody = xml_node_create(ctx->xml, syncml, NULL, "SyncBody");
304d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (syncbody == NULL) {
305d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_free(ctx->xml, syncml);
306d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
307d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
308d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
309d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	cmdid++;
310d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	add_alert(ctx, syncbody, cmdid, DM_CLIENT_INITIATED_MGMT);
311d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
312d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	str = mo_str(ctx, NULL, "devdetail.xml");
313d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (str == NULL) {
314d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_free(ctx->xml, syncml);
315d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
316d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
317d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	cmdid++;
318d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	oma_dm_add_hs20_generic_alert(ctx, syncbody, cmdid, oper, str);
319d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	os_free(str);
320d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
321d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	cmdid++;
322d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	add_replace_devinfo(ctx, syncbody, cmdid);
323d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
324d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create(ctx->xml, syncbody, NULL, "Final");
325d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
326d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return syncml;
327d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
328d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
329d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
330d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic xml_node_t * build_oma_dm_1_sub_reg(struct hs20_osu_client *ctx,
331d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					   const char *url, int msgid)
332d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
333d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *syncml;
334d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
335d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	syncml = build_oma_dm_1(ctx, url, msgid, DM_HS20_SUBSCRIPTION_CREATION);
336d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (syncml)
337d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		debug_dump_node(ctx, "OMA-DM Package 1 (sub reg)", syncml);
338d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
339d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return syncml;
340d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
341d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
342d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
343d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic xml_node_t * build_oma_dm_1_sub_prov(struct hs20_osu_client *ctx,
344d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					    const char *url, int msgid)
345d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
346d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *syncml;
347d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
348d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	syncml = build_oma_dm_1(ctx, url, msgid,
349d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				DM_HS20_SUBSCRIPTION_PROVISIONING);
350d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (syncml)
351d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		debug_dump_node(ctx, "OMA-DM Package 1 (sub prov)", syncml);
352d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
353d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return syncml;
354d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
355d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
356d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
357d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic xml_node_t * build_oma_dm_1_pol_upd(struct hs20_osu_client *ctx,
358d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					   const char *url, int msgid)
359d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
360d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *syncml;
361d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
362d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	syncml = build_oma_dm_1(ctx, url, msgid, DM_HS20_POLICY_UPDATE);
363d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (syncml)
364d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		debug_dump_node(ctx, "OMA-DM Package 1 (pol upd)", syncml);
365d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
366d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return syncml;
367d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
368d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
369d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
370d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic xml_node_t * build_oma_dm_1_sub_rem(struct hs20_osu_client *ctx,
371d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					   const char *url, int msgid)
372d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
373d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *syncml;
374d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
375d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	syncml = build_oma_dm_1(ctx, url, msgid,
376d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				DM_HS20_SUBSCRIPTION_REMEDIATION);
377d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (syncml)
378d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		debug_dump_node(ctx, "OMA-DM Package 1 (sub rem)", syncml);
379d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
380d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return syncml;
381d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
382d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
383d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
384d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int oma_dm_exec_browser(struct hs20_osu_client *ctx, xml_node_t *exec)
385d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
386d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *node;
387d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *data;
388d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int res;
389d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
390d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	node = get_node(ctx->xml, exec, "Item/Data");
391d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (node == NULL) {
392d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "No Data node found");
393d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_BAD_REQUEST;
394d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
395d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
396d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	data = xml_node_get_text(ctx->xml, node);
3977f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	if (data == NULL) {
3987f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		wpa_printf(MSG_INFO, "Invalid data");
3997f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		return DM_RESP_BAD_REQUEST;
4007f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	}
401d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Data: %s", data);
402d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Launch browser to URI '%s'", data);
403d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	write_summary(ctx, "Launch browser to URI '%s'", data);
404d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	res = hs20_web_browser(data);
405d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_get_text_free(ctx->xml, data);
406d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (res > 0) {
407d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "User response in browser completed successfully");
408d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		write_summary(ctx, "User response in browser completed successfully");
409d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_OK;
410d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	} else {
411d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Failed to receive user response");
412d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		write_summary(ctx, "Failed to receive user response");
413d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_COMMAND_FAILED;
414d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
415d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
416d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
417d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
418d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int oma_dm_exec_get_cert(struct hs20_osu_client *ctx, xml_node_t *exec)
419d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
420d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *node, *getcert;
421d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *data;
422d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	const char *name;
423d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int res;
424d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
425d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Client certificate enrollment");
426d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	write_summary(ctx, "Client certificate enrollment");
427d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
428d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	node = get_node(ctx->xml, exec, "Item/Data");
429d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (node == NULL) {
430d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "No Data node found");
431d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_BAD_REQUEST;
432d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
433d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
434d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	data = xml_node_get_text(ctx->xml, node);
4357f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	if (data == NULL) {
4367f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		wpa_printf(MSG_INFO, "Invalid data");
4377f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		return DM_RESP_BAD_REQUEST;
4387f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	}
439d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Data: %s", data);
440d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	getcert = xml_node_from_buf(ctx->xml, data);
441d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_get_text_free(ctx->xml, data);
442d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
443d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (getcert == NULL) {
444d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Could not parse Item/Data node contents");
445d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_BAD_REQUEST;
446d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
447d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
448d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	debug_dump_node(ctx, "OMA-DM getCertificate", getcert);
449d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
450d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	name = xml_node_get_localname(ctx->xml, getcert);
451d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (name == NULL || os_strcasecmp(name, "getCertificate") != 0) {
452d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Unexpected getCertificate node name '%s'",
453d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			   name);
454d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_BAD_REQUEST;
455d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
456d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
457d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	res = osu_get_certificate(ctx, getcert);
458d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
459d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_free(ctx->xml, getcert);
460d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
461d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return res == 0 ? DM_RESP_OK : DM_RESP_COMMAND_FAILED;
462d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
463d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
464d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
465d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int oma_dm_exec(struct hs20_osu_client *ctx, xml_node_t *exec)
466d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
467d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *locuri;
468d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int ret;
469d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
470d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	locuri = oma_dm_get_target_locuri(ctx, exec);
471d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (locuri == NULL) {
472d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "No Target LocURI node found");
473d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_BAD_REQUEST;
474d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
475d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
476d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Target LocURI: %s", locuri);
477d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
478d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (os_strcasecmp(locuri, "./DevDetail/Ext/org.wi-fi/Wi-Fi/Ops/"
479d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			  "launchBrowserToURI") == 0) {
480d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		ret = oma_dm_exec_browser(ctx, exec);
481d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	} else if (os_strcasecmp(locuri, "./DevDetail/Ext/org.wi-fi/Wi-Fi/Ops/"
482d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			  "getCertificate") == 0) {
483d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		ret = oma_dm_exec_get_cert(ctx, exec);
484d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	} else {
485d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Unsupported exec Target LocURI");
486d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		ret = DM_RESP_NOT_FOUND;
487d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
488d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	os_free(locuri);
489d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
490d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return ret;
491d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
492d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
493d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
494d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int oma_dm_run_add(struct hs20_osu_client *ctx, const char *locuri,
495d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			  xml_node_t *add, xml_node_t *pps,
496d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			  const char *pps_fname)
497d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
498d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	const char *pos;
499d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	size_t fqdn_len;
500d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *node, *tnds, *unode, *pps_node;
501d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *data, *uri, *upos, *end;
502d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int use_tnds = 0;
503d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	size_t uri_len;
504d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
505d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Add command target LocURI: %s", locuri);
506d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
507d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (os_strncasecmp(locuri, "./Wi-Fi/", 8) != 0) {
508d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Do not allow Add outside ./Wi-Fi");
509d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_PERMISSION_DENIED;
510d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
511d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	pos = locuri + 8;
512d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
513d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (ctx->fqdn == NULL)
514d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_COMMAND_FAILED;
515d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	fqdn_len = os_strlen(ctx->fqdn);
516d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (os_strncasecmp(pos, ctx->fqdn, fqdn_len) != 0 ||
517d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	    pos[fqdn_len] != '/') {
518d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Do not allow Add outside ./Wi-Fi/%s",
519d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			   ctx->fqdn);
520d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_PERMISSION_DENIED;
521d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
522d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	pos += fqdn_len + 1;
523d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
524d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (os_strncasecmp(pos, "PerProviderSubscription/", 24) != 0) {
525d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO,
526d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			   "Do not allow Add outside ./Wi-Fi/%s/PerProviderSubscription",
527d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			   ctx->fqdn);
528d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_PERMISSION_DENIED;
529d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
530d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	pos += 24;
531d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
532d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Add command for PPS node %s", pos);
533d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
534d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	pps_node = get_node(ctx->xml, pps, pos);
535d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (pps_node) {
536d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Specified PPS node exists already");
537d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_ALREADY_EXISTS;
538d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
539d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
540d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	uri = os_strdup(pos);
541d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (uri == NULL)
542d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_COMMAND_FAILED;
543d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	while (!pps_node) {
544d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		upos = os_strrchr(uri, '/');
545d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (!upos)
546d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			break;
547d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		upos[0] = '\0';
548d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		pps_node = get_node(ctx->xml, pps, uri);
549d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Node %s %s", uri,
550d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			   pps_node ? "exists" : "does not exist");
551d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
552d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
553d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Parent URI: %s", uri);
554d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
555d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (!pps_node) {
556d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		/* Add at root of PPS MO */
557d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		pps_node = pps;
558d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
559d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
560d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	uri_len = os_strlen(uri);
561d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	os_strlcpy(uri, pos + uri_len, os_strlen(pos));
562d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	upos = uri;
563d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	while (*upos == '/')
564d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		upos++;
565d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Nodes to add: %s", upos);
566d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
567d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	for (;;) {
568d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		end = os_strchr(upos, '/');
569d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (!end)
570d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			break;
571d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		*end = '\0';
572d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Adding interim node %s", upos);
573d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		pps_node = xml_node_create(ctx->xml, pps_node, NULL, upos);
574d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (pps_node == NULL) {
575d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			os_free(uri);
576d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return DM_RESP_COMMAND_FAILED;
577d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
578d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		upos = end + 1;
579d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
580d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
581d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Adding node %s", upos);
582d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
583d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	node = get_node(ctx->xml, add, "Item/Meta/Type");
584d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (node) {
585d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		char *type;
586d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		type = xml_node_get_text(ctx->xml, node);
5877f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		if (type == NULL) {
5887f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			wpa_printf(MSG_ERROR, "Could not find type text");
5897f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			os_free(uri);
5907f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt			return DM_RESP_BAD_REQUEST;
5917f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		}
592d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		use_tnds = node &&
593d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			os_strstr(type, "application/vnd.syncml.dmtnds+xml");
594d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
595d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
596d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	node = get_node(ctx->xml, add, "Item/Data");
597d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (node == NULL) {
598d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "No Add/Item/Data found");
599d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_free(uri);
600d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_BAD_REQUEST;
601d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
602d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
603d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	data = xml_node_get_text(ctx->xml, node);
604d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (data == NULL) {
605d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Could not get Add/Item/Data text");
606d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_free(uri);
607d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_BAD_REQUEST;
608d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
609d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
610d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_DEBUG, "Add/Item/Data: %s", data);
611d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
612d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (use_tnds) {
613d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		tnds = xml_node_from_buf(ctx->xml, data);
614d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_get_text_free(ctx->xml, data);
615d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (tnds == NULL) {
616d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			wpa_printf(MSG_INFO,
617d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				   "Could not parse Add/Item/Data text");
618d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			os_free(uri);
619d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return DM_RESP_BAD_REQUEST;
620d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
621d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
622d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		unode = tnds_to_mo(ctx->xml, tnds);
623d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_free(ctx->xml, tnds);
624d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (unode == NULL) {
625d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			wpa_printf(MSG_INFO, "Could not parse TNDS text");
626d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			os_free(uri);
627d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return DM_RESP_BAD_REQUEST;
628d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
629d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
630d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		debug_dump_node(ctx, "Parsed TNDS", unode);
631d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
632d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_add_child(ctx->xml, pps_node, unode);
633d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	} else {
634d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		/* TODO: What to do here? */
635d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_free(uri);
636d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_BAD_REQUEST;
637d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
638d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
639d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	os_free(uri);
640d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
641d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (update_pps_file(ctx, pps_fname, pps) < 0)
642d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_COMMAND_FAILED;
643d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
644d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	ctx->pps_updated = 1;
645d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
646d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return DM_RESP_OK;
647d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
648d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
649d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
650d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int oma_dm_add(struct hs20_osu_client *ctx, xml_node_t *add,
651d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		      xml_node_t *pps, const char *pps_fname)
652d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
653d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *node;
654d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *locuri;
655d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char fname[300];
656d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int ret;
657d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
658d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	node = get_node(ctx->xml, add, "Item/Target/LocURI");
659d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (node == NULL) {
660d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "No Target LocURI node found");
661d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_BAD_REQUEST;
662d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
663d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	locuri = xml_node_get_text(ctx->xml, node);
6647f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	if (locuri == NULL) {
6657f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		wpa_printf(MSG_ERROR, "No LocURI node text found");
6667f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt		return DM_RESP_BAD_REQUEST;
6677f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt	}
668d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Target LocURI: %s", locuri);
669d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (os_strncasecmp(locuri, "./Wi-Fi/", 8) != 0) {
670d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Unsupported Add Target LocURI");
671d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_get_text_free(ctx->xml, locuri);
672d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_PERMISSION_DENIED;
673d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
674d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
675d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	node = get_node(ctx->xml, add, "Item/Data");
676d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (node == NULL) {
677d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "No Data node found");
678d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_get_text_free(ctx->xml, locuri);
679d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_BAD_REQUEST;
680d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
681d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
682d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (pps_fname && os_file_exists(pps_fname)) {
683d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		ret = oma_dm_run_add(ctx, locuri, add, pps, pps_fname);
684d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (ret != DM_RESP_OK) {
685d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			xml_node_get_text_free(ctx->xml, locuri);
686d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return ret;
687d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
688d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		ret = 0;
689d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_strlcpy(fname, pps_fname, sizeof(fname));
690d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	} else
691d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		ret = hs20_add_pps_mo(ctx, locuri, node, fname, sizeof(fname));
692d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_get_text_free(ctx->xml, locuri);
693d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (ret < 0)
694d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return ret == -2 ? DM_RESP_ALREADY_EXISTS :
695d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			DM_RESP_COMMAND_FAILED;
696d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
697d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (ctx->no_reconnect == 2) {
698d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_snprintf(ctx->pps_fname, sizeof(ctx->pps_fname), "%s",
699d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			    fname);
700d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		ctx->pps_cred_set = 1;
701d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_OK;
702d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
703d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
704d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Updating wpa_supplicant credentials");
705d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	cmd_set_pps(ctx, fname);
706d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
707d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (ctx->no_reconnect)
708d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_OK;
709d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
710d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Requesting reconnection with updated configuration");
711d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (wpa_command(ctx->ifname, "INTERWORKING_SELECT auto") < 0)
712d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Failed to request wpa_supplicant to reconnect");
713d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
714d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return DM_RESP_OK;
715d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
716d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
717d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
718d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int oma_dm_replace(struct hs20_osu_client *ctx, xml_node_t *replace,
719d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			  xml_node_t *pps, const char *pps_fname)
720d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
721d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *locuri, *pos;
722d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	size_t fqdn_len;
723d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *node, *tnds, *unode, *pps_node, *parent;
724d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *data;
725d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int use_tnds = 0;
726d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
727d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	locuri = oma_dm_get_target_locuri(ctx, replace);
728d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (locuri == NULL)
729d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_BAD_REQUEST;
730d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
731d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Replace command target LocURI: %s", locuri);
732d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (os_strncasecmp(locuri, "./Wi-Fi/", 8) != 0) {
733d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Do not allow Replace outside ./Wi-Fi");
734d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_free(locuri);
735d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_PERMISSION_DENIED;
736d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
737d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	pos = locuri + 8;
738d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
739d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (ctx->fqdn == NULL) {
740d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_free(locuri);
741d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_COMMAND_FAILED;
742d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
743d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	fqdn_len = os_strlen(ctx->fqdn);
744d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (os_strncasecmp(pos, ctx->fqdn, fqdn_len) != 0 ||
745d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	    pos[fqdn_len] != '/') {
746d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Do not allow Replace outside ./Wi-Fi/%s",
747d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			   ctx->fqdn);
748d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_free(locuri);
749d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_PERMISSION_DENIED;
750d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
751d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	pos += fqdn_len + 1;
752d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
753d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (os_strncasecmp(pos, "PerProviderSubscription/", 24) != 0) {
754d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO,
755d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			   "Do not allow Replace outside ./Wi-Fi/%s/PerProviderSubscription",
756d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			   ctx->fqdn);
757d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_free(locuri);
758d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_PERMISSION_DENIED;
759d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
760d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	pos += 24;
761d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
762d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Replace command for PPS node %s", pos);
763d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
764d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	pps_node = get_node(ctx->xml, pps, pos);
765d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (pps_node == NULL) {
766d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Specified PPS node not found");
767d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_free(locuri);
768d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_NOT_FOUND;
769d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
770d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
771d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	node = get_node(ctx->xml, replace, "Item/Meta/Type");
772d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (node) {
773d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		char *type;
774d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		type = xml_node_get_text(ctx->xml, node);
7754dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt		if (type == NULL) {
7764dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt			wpa_printf(MSG_INFO, "Could not find type text");
7774dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt			os_free(locuri);
7784dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt			return DM_RESP_BAD_REQUEST;
7794dd28dc25895165566a1c8a9cac7bcd755ff8fe3Dmitry Shmidt		}
780d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		use_tnds = node &&
781d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			os_strstr(type, "application/vnd.syncml.dmtnds+xml");
782d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
783d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
784d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	node = get_node(ctx->xml, replace, "Item/Data");
785d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (node == NULL) {
786d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "No Replace/Item/Data found");
787d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_free(locuri);
788d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_BAD_REQUEST;
789d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
790d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
791d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	data = xml_node_get_text(ctx->xml, node);
792d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (data == NULL) {
793d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Could not get Replace/Item/Data text");
794d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_free(locuri);
795d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_BAD_REQUEST;
796d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
797d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
798d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_DEBUG, "Replace/Item/Data: %s", data);
799d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
800d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (use_tnds) {
801d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		tnds = xml_node_from_buf(ctx->xml, data);
802d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_get_text_free(ctx->xml, data);
803d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (tnds == NULL) {
804d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			wpa_printf(MSG_INFO,
805d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				   "Could not parse Replace/Item/Data text");
806d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			os_free(locuri);
807d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return DM_RESP_BAD_REQUEST;
808d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
809d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
810d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		unode = tnds_to_mo(ctx->xml, tnds);
811d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_free(ctx->xml, tnds);
812d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (unode == NULL) {
813d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			wpa_printf(MSG_INFO, "Could not parse TNDS text");
814d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			os_free(locuri);
815d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return DM_RESP_BAD_REQUEST;
816d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
817d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
818d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		debug_dump_node(ctx, "Parsed TNDS", unode);
819d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
820d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		parent = xml_node_get_parent(ctx->xml, pps_node);
821d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_detach(ctx->xml, pps_node);
822d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_add_child(ctx->xml, parent, unode);
823d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	} else {
824d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_set_text(ctx->xml, pps_node, data);
825d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_get_text_free(ctx->xml, data);
826d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
827d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
828d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	os_free(locuri);
829d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
830d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (update_pps_file(ctx, pps_fname, pps) < 0)
831d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_COMMAND_FAILED;
832d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
833d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	ctx->pps_updated = 1;
834d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
835d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return DM_RESP_OK;
836d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
837d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
838d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
839d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int oma_dm_get(struct hs20_osu_client *ctx, xml_node_t *get,
840d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		      xml_node_t *pps, const char *pps_fname, char **value)
841d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
842d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *locuri, *pos;
843d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	size_t fqdn_len;
844d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *pps_node;
845d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	const char *name;
846d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
847d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	*value = NULL;
848d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
849d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	locuri = oma_dm_get_target_locuri(ctx, get);
850d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (locuri == NULL)
851d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_BAD_REQUEST;
852d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
853d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Get command target LocURI: %s", locuri);
854d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (os_strncasecmp(locuri, "./Wi-Fi/", 8) != 0) {
855d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Do not allow Get outside ./Wi-Fi");
856d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_free(locuri);
857d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_PERMISSION_DENIED;
858d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
859d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	pos = locuri + 8;
860d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
861d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (ctx->fqdn == NULL)
862d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_COMMAND_FAILED;
863d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	fqdn_len = os_strlen(ctx->fqdn);
864d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (os_strncasecmp(pos, ctx->fqdn, fqdn_len) != 0 ||
865d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	    pos[fqdn_len] != '/') {
866d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Do not allow Get outside ./Wi-Fi/%s",
867d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			   ctx->fqdn);
868d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_free(locuri);
869d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_PERMISSION_DENIED;
870d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
871d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	pos += fqdn_len + 1;
872d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
873d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (os_strncasecmp(pos, "PerProviderSubscription/", 24) != 0) {
874d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO,
875d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			   "Do not allow Get outside ./Wi-Fi/%s/PerProviderSubscription",
876d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			   ctx->fqdn);
877d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_free(locuri);
878d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_PERMISSION_DENIED;
879d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
880d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	pos += 24;
881d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
882d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Get command for PPS node %s", pos);
883d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
884d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	pps_node = get_node(ctx->xml, pps, pos);
885d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (pps_node == NULL) {
886d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Specified PPS node not found");
887d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_free(locuri);
888d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_NOT_FOUND;
889d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
890d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
891d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	name = xml_node_get_localname(ctx->xml, pps_node);
892d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Get command returned node with name '%s'", name);
893d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (os_strcasecmp(name, "Password") == 0) {
894d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Do not allow Get for Password node");
895d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_free(locuri);
896d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_PERMISSION_DENIED;
897d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
898d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
899d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	/*
900d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	 * TODO: No support for DMTNDS, so if interior node, reply with a
901d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	 * list of children node names in Results element. The child list type is
902d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	 * defined in [DMTND].
903d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	 */
904d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
905d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	*value = xml_node_get_text(ctx->xml, pps_node);
906d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (*value == NULL)
907d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return DM_RESP_COMMAND_FAILED;
908d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
909d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return DM_RESP_OK;
910d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
911d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
912d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
913d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic int oma_dm_get_cmdid(struct hs20_osu_client *ctx, xml_node_t *node)
914d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
915d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *cnode;
916d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *str;
917d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int ret;
918d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
919d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	cnode = get_node(ctx->xml, node, "CmdID");
920d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (cnode == NULL)
921d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return 0;
922d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
923d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	str = xml_node_get_text(ctx->xml, cnode);
924d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (str == NULL)
925d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return 0;
926d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	ret = atoi(str);
927d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_get_text_free(ctx->xml, str);
928d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return ret;
929d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
930d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
931d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
932d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic xml_node_t * oma_dm_send_recv(struct hs20_osu_client *ctx,
933d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				     const char *url, xml_node_t *syncml,
9346cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt				     const char *ext_hdr,
935d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				     const char *username, const char *password,
936d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				     const char *client_cert,
937d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				     const char *client_key)
938d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
939d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *resp;
940d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *str, *res;
941d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *resp_uri = NULL;
942d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
943d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	str = xml_node_to_str(ctx->xml, syncml);
944d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_free(ctx->xml, syncml);
945d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (str == NULL)
946d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
947d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
948d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Send OMA DM Package");
949d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	write_summary(ctx, "Send OMA DM Package");
950d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	os_free(ctx->server_url);
951d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	ctx->server_url = os_strdup(url);
952d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	res = http_post(ctx->http, url, str, "application/vnd.syncml.dm+xml",
9536cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt			ext_hdr, ctx->ca_fname, username, password,
954d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			client_cert, client_key, NULL);
955d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	os_free(str);
956d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	os_free(resp_uri);
957d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	resp_uri = NULL;
958d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
959d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (res == NULL) {
960d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		const char *err = http_get_err(ctx->http);
961d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (err) {
962d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			wpa_printf(MSG_INFO, "HTTP error: %s", err);
963d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			write_result(ctx, "HTTP error: %s", err);
964d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		} else {
965d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			write_summary(ctx, "Failed to send OMA DM Package");
966d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
967d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
968d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
969d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_DEBUG, "Server response: %s", res);
970d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
971d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Process OMA DM Package");
972d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	write_summary(ctx, "Process received OMA DM Package");
973d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	resp = xml_node_from_buf(ctx->xml, res);
974d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	os_free(res);
975d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (resp == NULL) {
976d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Failed to parse OMA DM response");
977d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
978d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
979d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
980d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	debug_dump_node(ctx, "OMA DM Package", resp);
981d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
982d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return resp;
983d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
984d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
985d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
986d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtstatic xml_node_t * oma_dm_process(struct hs20_osu_client *ctx, const char *url,
987d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				   xml_node_t *resp, int msgid,
988d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				   char **ret_resp_uri,
989d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				   xml_node_t *pps, const char *pps_fname)
990d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
991d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *syncml, *syncbody, *hdr, *body, *child;
992d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	const char *name;
993d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *resp_uri = NULL;
994d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int server_msgid = 0;
995d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int cmdid = 0;
996d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int server_cmdid;
997d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int resp_needed = 0;
998d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *tmp;
999d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int final = 0;
1000d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *locuri;
1001d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1002d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	*ret_resp_uri = NULL;
1003d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1004d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	name = xml_node_get_localname(ctx->xml, resp);
1005d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (name == NULL || os_strcasecmp(name, "SyncML") != 0) {
1006d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "SyncML node not found");
1007d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
1008d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1009d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1010d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	hdr = get_node(ctx->xml, resp, "SyncHdr");
1011d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	body = get_node(ctx->xml, resp, "SyncBody");
1012d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (hdr == NULL || body == NULL) {
1013d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Could not find SyncHdr or SyncBody");
1014d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
1015d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1016d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1017d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_for_each_child(ctx->xml, child, hdr) {
1018d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_for_each_check(ctx->xml, child);
1019d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		name = xml_node_get_localname(ctx->xml, child);
1020d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "SyncHdr %s", name);
1021d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (os_strcasecmp(name, "RespURI") == 0) {
1022d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			tmp = xml_node_get_text(ctx->xml, child);
1023d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			if (tmp)
1024d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				resp_uri = os_strdup(tmp);
1025d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			xml_node_get_text_free(ctx->xml, tmp);
1026d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		} else if (os_strcasecmp(name, "MsgID") == 0) {
1027d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			tmp = xml_node_get_text(ctx->xml, child);
1028d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			if (tmp)
1029d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				server_msgid = atoi(tmp);
1030d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			xml_node_get_text_free(ctx->xml, tmp);
1031d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
1032d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1033d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1034d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Server MsgID: %d", server_msgid);
1035d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (resp_uri)
1036d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "RespURI: %s", resp_uri);
1037d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1038d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	syncml = oma_dm_build_hdr(ctx, resp_uri ? resp_uri : url, msgid);
1039d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (syncml == NULL) {
1040d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_free(resp_uri);
1041d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
1042d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1043d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1044d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	syncbody = xml_node_create(ctx->xml, syncml, NULL, "SyncBody");
1045d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	cmdid++;
1046d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	add_status(ctx, syncbody, server_msgid, 0, cmdid, "SyncHdr",
1047d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		   DM_RESP_AUTH_ACCEPTED, NULL);
1048d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1049d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_for_each_child(ctx->xml, child, body) {
1050d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_for_each_check(ctx->xml, child);
1051d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		server_cmdid = oma_dm_get_cmdid(ctx, child);
1052d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		name = xml_node_get_localname(ctx->xml, child);
1053d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "SyncBody CmdID=%d - %s",
1054d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			   server_cmdid, name);
1055d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (os_strcasecmp(name, "Exec") == 0) {
1056d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			int res = oma_dm_exec(ctx, child);
1057d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			cmdid++;
1058d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			locuri = oma_dm_get_target_locuri(ctx, child);
1059d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			if (locuri == NULL)
1060d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				res = DM_RESP_BAD_REQUEST;
1061d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			add_status(ctx, syncbody, server_msgid, server_cmdid,
1062d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				   cmdid, name, res, locuri);
1063d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			os_free(locuri);
1064d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			resp_needed = 1;
1065d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		} else if (os_strcasecmp(name, "Add") == 0) {
1066d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			int res = oma_dm_add(ctx, child, pps, pps_fname);
1067d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			cmdid++;
1068d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			locuri = oma_dm_get_target_locuri(ctx, child);
1069d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			if (locuri == NULL)
1070d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				res = DM_RESP_BAD_REQUEST;
1071d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			add_status(ctx, syncbody, server_msgid, server_cmdid,
1072d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				   cmdid, name, res, locuri);
1073d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			os_free(locuri);
1074d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			resp_needed = 1;
1075d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		} else if (os_strcasecmp(name, "Replace") == 0) {
1076d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			int res;
1077d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			res = oma_dm_replace(ctx, child, pps, pps_fname);
1078d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			cmdid++;
1079d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			locuri = oma_dm_get_target_locuri(ctx, child);
1080d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			if (locuri == NULL)
1081d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				res = DM_RESP_BAD_REQUEST;
1082d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			add_status(ctx, syncbody, server_msgid, server_cmdid,
1083d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				   cmdid, name, res, locuri);
1084d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			os_free(locuri);
1085d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			resp_needed = 1;
1086d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		} else if (os_strcasecmp(name, "Status") == 0) {
1087d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			/* TODO: Verify success */
1088d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		} else if (os_strcasecmp(name, "Get") == 0) {
1089d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			int res;
1090d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			char *value;
1091d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			res = oma_dm_get(ctx, child, pps, pps_fname, &value);
1092d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			cmdid++;
1093d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			locuri = oma_dm_get_target_locuri(ctx, child);
1094d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			if (locuri == NULL)
1095d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				res = DM_RESP_BAD_REQUEST;
1096d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			add_status(ctx, syncbody, server_msgid, server_cmdid,
1097d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				   cmdid, name, res, locuri);
1098d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			if (res == DM_RESP_OK && value) {
1099d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				cmdid++;
1100d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				add_results(ctx, syncbody, server_msgid,
1101d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					    server_cmdid, cmdid, locuri, value);
1102d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			}
1103d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			os_free(locuri);
1104d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			xml_node_get_text_free(ctx->xml, value);
1105d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			resp_needed = 1;
1106d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#if 0 /* TODO: MUST support */
1107d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		} else if (os_strcasecmp(name, "Delete") == 0) {
1108d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#endif
1109d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#if 0 /* TODO: MUST support */
1110d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		} else if (os_strcasecmp(name, "Sequence") == 0) {
1111d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt#endif
1112d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		} else if (os_strcasecmp(name, "Final") == 0) {
1113d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			final = 1;
1114d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			break;
1115d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		} else {
1116d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			locuri = oma_dm_get_target_locuri(ctx, child);
1117d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			add_status(ctx, syncbody, server_msgid, server_cmdid,
1118d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				   cmdid, name, DM_RESP_COMMAND_NOT_IMPLEMENTED,
1119d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				   locuri);
1120d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			os_free(locuri);
1121d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			resp_needed = 1;
1122d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
1123d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1124d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1125d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (!final) {
1126d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Final node not found");
1127d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_free(ctx->xml, syncml);
1128d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_free(resp_uri);
1129d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
1130d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1131d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1132d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (!resp_needed) {
1133d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Exchange completed - no response needed");
1134d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_free(ctx->xml, syncml);
1135d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		os_free(resp_uri);
1136d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return NULL;
1137d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1138d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1139d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_create(ctx->xml, syncbody, NULL, "Final");
1140d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1141d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	debug_dump_node(ctx, "OMA-DM Package 3", syncml);
1142d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1143d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	*ret_resp_uri = resp_uri;
1144d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return syncml;
1145d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
1146d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1147d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
11486cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidtint cmd_oma_dm_prov(struct hs20_osu_client *ctx, const char *url)
1149d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
1150d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *syncml, *resp;
1151d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *resp_uri = NULL;
1152d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int msgid = 0;
1153d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1154d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (url == NULL) {
1155d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Invalid prov command (missing URL)");
1156d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
1157d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1158d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1159d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "OMA-DM credential provisioning requested");
1160d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	write_summary(ctx, "OMA-DM credential provisioning");
1161d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1162d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	msgid++;
1163d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	syncml = build_oma_dm_1_sub_reg(ctx, url, msgid);
1164d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (syncml == NULL)
1165d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
1166d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1167d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	while (syncml) {
1168d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		resp = oma_dm_send_recv(ctx, resp_uri ? resp_uri : url,
11696cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt					syncml, NULL, NULL, NULL, NULL, NULL);
1170d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (resp == NULL)
1171d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return -1;
1172d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1173d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		msgid++;
1174d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		syncml = oma_dm_process(ctx, url, resp, msgid, &resp_uri,
1175d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					NULL, NULL);
1176d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_free(ctx->xml, resp);
1177d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1178d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1179d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	os_free(resp_uri);
1180d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1181d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return ctx->pps_cred_set ? 0 : -1;
1182d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
1183d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1184d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
11856cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidtint cmd_oma_dm_sim_prov(struct hs20_osu_client *ctx, const char *url)
1186d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
1187d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *syncml, *resp;
1188d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *resp_uri = NULL;
1189d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int msgid = 0;
1190d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1191d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (url == NULL) {
1192d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Invalid prov command (missing URL)");
1193d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
1194d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1195d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1196d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "OMA-DM SIM provisioning requested");
1197d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	ctx->no_reconnect = 2;
1198d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1199d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Wait for IP address before starting SIM provisioning");
1200d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	write_summary(ctx, "Wait for IP address before starting SIM provisioning");
1201d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1202d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (wait_ip_addr(ctx->ifname, 15) < 0) {
1203d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Could not get IP address for WLAN - try connection anyway");
1204d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1205d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	write_summary(ctx, "OMA-DM SIM provisioning");
1206d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1207d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	msgid++;
1208d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	syncml = build_oma_dm_1_sub_prov(ctx, url, msgid);
1209d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (syncml == NULL)
1210d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return -1;
1211d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1212d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	while (syncml) {
1213d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		resp = oma_dm_send_recv(ctx, resp_uri ? resp_uri : url,
12146cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt					syncml, NULL, NULL, NULL, NULL, NULL);
1215d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (resp == NULL)
1216d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return -1;
1217d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1218d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		msgid++;
1219d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		syncml = oma_dm_process(ctx, url, resp, msgid, &resp_uri,
1220d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					NULL, NULL);
1221d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_free(ctx->xml, resp);
1222d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1223d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1224d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	os_free(resp_uri);
1225d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1226d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (ctx->pps_cred_set) {
1227d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Updating wpa_supplicant credentials");
1228d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		cmd_set_pps(ctx, ctx->pps_fname);
1229d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1230d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Requesting reconnection with updated configuration");
1231d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		write_summary(ctx, "Requesting reconnection with updated configuration");
1232d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (wpa_command(ctx->ifname, "INTERWORKING_SELECT auto") < 0) {
1233d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			wpa_printf(MSG_INFO, "Failed to request wpa_supplicant to reconnect");
1234d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			write_summary(ctx, "Failed to request wpa_supplicant to reconnect");
1235d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return -1;
1236d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
1237d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1238d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1239d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	return ctx->pps_cred_set ? 0 : -1;
1240d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
1241d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1242d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1243d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtvoid oma_dm_pol_upd(struct hs20_osu_client *ctx, const char *address,
12446cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt		    const char *pps_fname,
1245d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		    const char *client_cert, const char *client_key,
1246d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		    const char *cred_username, const char *cred_password,
1247d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		    xml_node_t *pps)
1248d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
1249d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *syncml, *resp;
1250d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *resp_uri = NULL;
1251d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int msgid = 0;
1252d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1253d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "OMA-DM policy update");
1254d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	write_summary(ctx, "OMA-DM policy update");
1255d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1256d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	msgid++;
1257d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	syncml = build_oma_dm_1_pol_upd(ctx, address, msgid);
1258d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (syncml == NULL)
1259d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return;
1260d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1261d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	while (syncml) {
1262d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		resp = oma_dm_send_recv(ctx, resp_uri ? resp_uri : address,
12636cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt					syncml, NULL, cred_username,
1264d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					cred_password, client_cert, client_key);
1265d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (resp == NULL)
1266d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return;
1267d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1268d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		msgid++;
1269d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		syncml = oma_dm_process(ctx, address, resp, msgid, &resp_uri,
1270d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					pps, pps_fname);
1271d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_free(ctx->xml, resp);
1272d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1273d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1274d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	os_free(resp_uri);
1275d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1276d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (ctx->pps_updated) {
1277d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Update wpa_supplicant credential based on updated PPS MO");
1278d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		write_summary(ctx, "Update wpa_supplicant credential based on updated PPS MO and request connection");
1279d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		cmd_set_pps(ctx, pps_fname);
1280d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (wpa_command(ctx->ifname, "INTERWORKING_SELECT auto") < 0) {
1281d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			wpa_printf(MSG_INFO,
1282d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				   "Failed to request wpa_supplicant to reconnect");
1283d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			write_summary(ctx,
1284d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt				      "Failed to request wpa_supplicant to reconnect");
1285d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		}
1286d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1287d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
1288d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1289d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1290d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtvoid oma_dm_sub_rem(struct hs20_osu_client *ctx, const char *address,
12916cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt		    const char *pps_fname,
1292d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		    const char *client_cert, const char *client_key,
1293d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		    const char *cred_username, const char *cred_password,
1294d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		    xml_node_t *pps)
1295d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
1296d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *syncml, *resp;
1297d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	char *resp_uri = NULL;
1298d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int msgid = 0;
1299d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1300d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "OMA-DM subscription remediation");
1301d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	write_summary(ctx, "OMA-DM subscription remediation");
1302d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1303d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	msgid++;
1304d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	syncml = build_oma_dm_1_sub_rem(ctx, address, msgid);
1305d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (syncml == NULL)
1306d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return;
1307d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1308d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	while (syncml) {
1309d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		resp = oma_dm_send_recv(ctx, resp_uri ? resp_uri : address,
13106cb1f6521a84955752c2b99100cf1df87637f86cDmitry Shmidt					syncml, NULL, cred_username,
1311d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					cred_password, client_cert, client_key);
1312d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		if (resp == NULL)
1313d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			return;
1314d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1315d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		msgid++;
1316d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		syncml = oma_dm_process(ctx, address, resp, msgid, &resp_uri,
1317d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt					pps, pps_fname);
1318d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_free(ctx->xml, resp);
1319d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1320d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1321d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	os_free(resp_uri);
1322d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1323d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "Update wpa_supplicant credential based on updated PPS MO and request reconnection");
1324d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	write_summary(ctx, "Update wpa_supplicant credential based on updated PPS MO and request reconnection");
1325d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	cmd_set_pps(ctx, pps_fname);
1326d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (wpa_command(ctx->ifname, "INTERWORKING_SELECT auto") < 0) {
1327d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Failed to request wpa_supplicant to reconnect");
1328d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		write_summary(ctx, "Failed to request wpa_supplicant to reconnect");
1329d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1330d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
1331d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1332d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1333d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtvoid cmd_oma_dm_add(struct hs20_osu_client *ctx, const char *pps_fname,
1334d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		    const char *add_fname)
1335d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
1336d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *pps, *add;
1337d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int res;
1338d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1339d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	ctx->fqdn = os_strdup("wi-fi.org");
1340d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1341d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	pps = node_from_file(ctx->xml, pps_fname);
1342d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (pps == NULL) {
1343d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "PPS file %s could not be parsed",
1344d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			   pps_fname);
1345d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return;
1346d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1347d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1348d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	add = node_from_file(ctx->xml, add_fname);
1349d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (add == NULL) {
1350d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Add file %s could not be parsed",
1351d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			   add_fname);
1352d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_free(ctx->xml, pps);
1353d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return;
1354d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1355d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1356d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	res = oma_dm_add(ctx, add, pps, pps_fname);
1357d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "oma_dm_add --> %d", res);
1358d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1359d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_free(ctx->xml, pps);
1360d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_free(ctx->xml, add);
1361d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
1362d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1363d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1364d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidtvoid cmd_oma_dm_replace(struct hs20_osu_client *ctx, const char *pps_fname,
1365d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			const char *replace_fname)
1366d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt{
1367d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_t *pps, *replace;
1368d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	int res;
1369d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1370d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	ctx->fqdn = os_strdup("wi-fi.org");
1371d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1372d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	pps = node_from_file(ctx->xml, pps_fname);
1373d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (pps == NULL) {
1374d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "PPS file %s could not be parsed",
1375d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			   pps_fname);
1376d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return;
1377d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1378d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1379d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	replace = node_from_file(ctx->xml, replace_fname);
1380d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	if (replace == NULL) {
1381d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		wpa_printf(MSG_INFO, "Replace file %s could not be parsed",
1382d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt			   replace_fname);
1383d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		xml_node_free(ctx->xml, pps);
1384d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt		return;
1385d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	}
1386d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1387d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	res = oma_dm_replace(ctx, replace, pps, pps_fname);
1388d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	wpa_printf(MSG_INFO, "oma_dm_replace --> %d", res);
1389d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt
1390d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_free(ctx->xml, pps);
1391d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt	xml_node_free(ctx->xml, replace);
1392d5dc24eb5fbf0e0feff214c0260cae845721d5feDmitry Shmidt}
1393