I am working on a USSD client. Everything works fine except for closing a distant USSD session.
In the specification, we can see the function CUSD:
AT+CUSD=2 should close the USSD session, but this is not really the case.
In fact when I do this sequence:
AT+CUSD='#xxx#',12
AT+CUSD='1',12
I have an open distant connection.
On your handset, you can open a new session by dialing #xxx*#
If I send a:
AT+CUSD='#xxx*#',12
This is not opening a new distant session.
If I send a:
AT+CUSD=2
AT+CUSD='#xxx#'
This is not opening a new distant session.
Do you know how to close a distant session?
I am working with huwaei key E160 and E173 on windows or Linux.
Use in the following way.
AT+CUSD='#xxx#',15
AT+CUSD=2
I am posting this because this is the top result regarding terminating USSD sessions using AT commands and also because the answers are vague.
This is the c# code i used in the end(I was sending the commands to a gsm modem). Hope it helps someone else
SerialPort SendingPort=null;
public string TerminateUssdSession()
{
InitializePort();
//// generate terminate command for modem
string cmd = "";
cmd = "AT+CUSD=2\r";
// send cmd to modem
OpenPort();
SendingPort.Write(cmd);
Thread.Sleep(500);
string response = SendingPort.ReadExisting();
return response;
}
private void InitializePort()
{
if (SendingPort == null)
{
SendingPort = new SerialPort();
SendingPort.PortName = PortName;//put portname here e.g COM5
SendingPort.BaudRate = "112500";
SendingPort.Parity = Parity.None;
SendingPort.DataBits = 8;
SendingPort.StopBits = StopBits.One;
SendingPort.Handshake = Handshake.None;
SendingPort.ReadTimeout = 500;
}
}
private void OpenPort()
{
if (!SendingPort.IsOpen)
{
SendingPort.Open();
}
}
Related
I'm trying to track the sms delivery status of the messages I send using the bot framework. I'm using Twilio, and sending proactive messages. Right now I'm trying to do so with twilio status callbacks
This is similar to this question, I tried that approach but I couldn't get it to work. I've added my url on the TwiML app and it is not firing. I have double and triple checked, and I suspect this url is somehow ignored or not going through with my current set up. I don't get any callbacks on the proactive message nor on the replies the bot sends to the user. However the flow works fine and I can reply and get proper responses from the bot. Edit: calling this "approach 1"
approach 2: I've also tried this doing some light modifications on Twilio adapter, to be able to add my callback just before create message. (I changed it so it uses a customized client wrapper that adds my callback url when creating the twilio resource) This does work, partially: when I reply a message from my bot, I get the status callbacks. But as the proactive message is sent using the default adapter, I don't get a callback on the initial message.
approach 3: Finally, I also tried using the TwilioAdapter when sending the proactive message but for some reason as soon as I send an activity, the TurnContext is disposed, so I can't save the state or do any subsequent actions. This leads me to believe twilio adapter is not intended to be used this way (can't be used on proactive messages), but I'm willing to explore this path if necessary.
Here is the modified Twilio Adapter:
public class TwilioAdapterWithErrorHandler : TwilioAdapter
{
private const string TwilioNumberKey = "TwilioNumber";
private const string TwilioAccountSidKey = "TwilioAccountSid";
private const string TwilioAuthTokenKey = "TwilioAuthToken";
private const string TwilioValidationUrlKey = "TwilioValidationUrl";
public TwilioAdapterWithErrorHandler(IConfiguration configuration, ILogger<TwilioAdapter> logger, TwilioAdapterOptions adapterOptions = null)
: base(
new TwilioClientWrapperWithCallback(new TwilioClientWrapperOptions(configuration[TwilioNumberKey], configuration[TwilioAccountSidKey], configuration[TwilioAuthTokenKey], new Uri(configuration[TwilioValidationUrlKey]))), adapterOptions, logger)
{
OnTurnError = async (turnContext, exception) =>
{
// Log any leaked exception from the application.
logger.LogError(exception, $"[OnTurnError] unhandled error : {exception.Message}");
Task[] tasks = {
// Send a message to the user
turnContext.SendActivityAsync("We're sorry but this bot encountered an error when processing your answer."),
// Send a trace activity, which will be displayed in the Bot Framework Emulator
turnContext.TraceActivityAsync("OnTurnError Trace", exception.Message, "https://www.botframework.com/schemas/error", "TurnError")
};
Task all = Task.WhenAll(tasks); //task with the long running tasks
await Task.WhenAny(all, Task.Delay(5000)); //wait with a timeout
};
}
}
Modified client Wrapper:
public class TwilioClientWrapperWithCallback : TwilioClientWrapper
{
public TwilioClientWrapperWithCallback(TwilioClientWrapperOptions options) : base(options) { }
public async override Task<string> SendMessageAsync(TwilioMessageOptions messageOptions, CancellationToken cancellationToken)
{
var createMessageOptions = new CreateMessageOptions(messageOptions.To)
{
ApplicationSid = messageOptions.ApplicationSid,
MediaUrl = messageOptions.MediaUrl,
Body = messageOptions.Body,
From = messageOptions.From,
};
createMessageOptions.StatusCallback = new System.Uri("https://myApp.ngrok.io/api/TwilioSms/SmsStatusUpdated");
var messageResource = await MessageResource.CreateAsync(createMessageOptions).ConfigureAwait(false);
return messageResource.Sid;
}
}
Finally, here's my summarized code that sends the proactive message:
[HttpPost("StartConversationWithSuperBill/{superBillId:long}")]
[HttpPost("StartConversationWithSuperBill/{superBillId:long}/Campaign/{campaignId:int}")]
public async Task<IActionResult> StartConversation(long superBillId, int? campaignId)
{
ConversationReference conversationReference = this.GetConversationReference("+17545517768");
//Start a new conversation.
await ((BotAdapter)_adapter).ContinueConversationAsync(_appId, conversationReference, async (turnContext, token) =>
{
await turnContext.SendActivityAsync("proactive message 1");
//this code was edited for brevity. Here I would start a new dialog that would cascade into another, but the end result is the same, as soon as a message is sent, the turn context is disposed.
await turnContext.SendActivityAsync("proactive message 2"); //throws ObjectDisposedException
}, default(CancellationToken));
var result = new { status = "Initialized fine!" };
return new JsonResult(result);
}
private ConversationReference GetConversationReference(string targetNumber)
{
string fromNumber = "+18632704234";
return new ConversationReference
{
User = new ChannelAccount { Id = targetNumber, Role = "user" },
Bot = new ChannelAccount { Id = fromNumber, Role = "bot" },
Conversation = new ConversationAccount { Id = targetNumber },
//ChannelId = "sms",
ChannelId = "twilio-sms", //appparently when using twilio adapter we need to set this. if using TwiML app and not using Twilio Adapter, use the above. Otherwise the frameworks interprets answers from SMS as new conversations instead.
ServiceUrl = "https://sms.botframework.com/",
};
}
(I can see that I could just call create conversation reference and do two callbacks, one for each message, but in my actual code I'm creating a dialog that sends one message and then invokes another dialog that starts another message)
Edit 2:
Some clarifications:
On approach 2, I'm using two adapters, as suggested by code sample and documentation on using twilio adapter. The controller that starts the proactive message uses an instance of a default adapter (similar to this one), and TwilioController (the one that gets the twilio incoming messages) uses TwilioAdapterWithErrorHandler.
On approach 3, I excluded the default adapter, and both controllers use TwilioAdapterWithErrorHandler.
Edit 3:
Here's a small repo with the issue.
I found a fix for this problem, around approach 3, by changing the overload I use for ContinueConversation. Replace this :
//Start a new conversation.
await ((BotAdapter)_adapter).ContinueConversationAsync(_appId, conversationReference, async (turnContext, token) =>
With this:
//Start a new conversation.
var twilioAdapter = (TwilioAdapterWithErrorHandler)_adapter;
await twilioAdapter.ContinueConversationAsync(_appId, conversationReference, async (context, token) =>
This way, the context is not disposed, an I can use the twilio adapter for the proactive message and have status callbacks on all messages.
I am aiming to make a post request to trigger a IFTTT webhook action. I am using the MKR1010 board. I am able to connect to the network and turn the connected LED on and off using the cloud integration.
The code is as follows, but doesn't trigger the web hook. I can manually paste the web address in a browser and this does trigger the web hook. When the code is posted it returns a 400 bad request error.
The key has been replaced in the below code with a dummy value.
Does anybody know why this is not triggering the web hook? / Can you explain why the post request is being rejected by the server? I don't even really need to read the response from the server as long as it is sent.
Thank you
// ArduinoHttpClient - Version: Latest
#include <ArduinoHttpClient.h>
#include "thingProperties.h"
#define LED_PIN 13
#define BTN1 6
char serverAddress[] = "maker.ifttt.com"; // server address
int port = 443;
WiFiClient wifi;
HttpClient client = HttpClient(wifi, serverAddress, port);
// variables will change:
int btnState = 0; // variable for reading the pushbutton status
int btnPrevState = 0;
void setup() {
// Initialize serial and wait for port to open:
Serial.begin(9600);
// This delay gives the chance to wait for a Serial Monitor without blocking if none is found
delay(1500);
// Defined in thingProperties.h
initProperties();
// Connect to Arduino IoT Cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
/*
The following function allows you to obtain more information
related to the state of network and IoT Cloud connection and errors
the higher number the more granular information you’ll get.
The default is 0 (only errors).
Maximum is 4
*/
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
// setup the board devices
pinMode(LED_PIN, OUTPUT);
pinMode(BTN1, INPUT);
}
void loop() {
ArduinoCloud.update();
// Your code here
// read the state of the pushbutton value:
btnState = digitalRead(BTN1);
if (btnPrevState == 0 && btnState == 1) {
led2 = !led2;
postrequest();
}
digitalWrite(LED_PIN, led2);
btnPrevState = btnState;
}
void onLed1Change() {
// Do something
digitalWrite(LED_PIN, led1);
//Serial.print("The light is ");
if (led1) {
Serial.println("The light is ON");
} else {
// Serial.println("OFF");
}
}
void onLed2Change() {
// Do something
digitalWrite(LED_PIN, led2);
}
void postrequest() {
// String("POST /trigger/btn1press/with/key/mykeyhere")
Serial.println("making POST request");
String contentType = "/trigger/btn1press/with/key";
String postData = "mykeyhere";
client.post("/", contentType, postData);
// read the status code and body of the response
int statusCode = client.responseStatusCode();
String response = client.responseBody();
Serial.print("Status code: ");
Serial.println(statusCode);
Serial.print("Response: ");
Serial.println(response);
Serial.println("Wait five seconds");
delay(5000);
}
Why do you want to make a POST request and send the key in the POST body? The browser sends a GET request. It would be
client.get("/trigger/btn1press/with/key/mykeyhere");
In HttpClient post() the first parameter is 'path', the second parameter is contentType (for example "text/plain") and the third parameter is the body of the HTTP POST request.
So your post should look like
client.post("/trigger/btn1press/with/key/mykeyhere", contentType, postData);
I am trying to get push notifications to work on iOS, but I can not get access to the device token!
My Unity version is 5.4.1f1.
I have enabled the Push Notifications capability in XCode and all the certificates are setup correctly:
In my script in the start method I call this:
UnityEngine.iOS.NotificationServices.RegisterForNotifications
(UnityEngine.iOS.NotificationType.Alert | UnityEngine.iOS.NotificationType.Badge
| UnityEngine.iOS.NotificationType.Sound, true);
Then from the update method I call this method:
private bool RegisterTokenWithPlayfab( System.Action successCallback,
System.Action<PlayFabError> errorCallback )
{
byte[] token = UnityEngine.iOS.NotificationServices.deviceToken;
if(token != null)
{
// Registration on backend
}
else
{
string errorDescription = UnityEngine.iOS.NotificationServices.registrationError;
Debug.Log( "Push Notifications Registration failed with: " + errorDescription );
return false;
}
}
The token keeps being empty, so the else-branch is entered every call. Also, the registrationError keeps being empty.
Can someone point me in the right direction on this? What else can I try or how can I get more infos on what is going wrong??
Try this one
Go to your application target. Choose Capabilities and ensure that ‘Push Notifications’ is enabled there.
You need to check deviceToken in a Coroutine or Update.
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
using NotificationServices = UnityEngine.iOS.NotificationServices;
using NotificationType = UnityEngine.iOS.NotificationType;
public class NotificationRegistrationExample : MonoBehaviour
{
bool tokenSent;
void Start()
{
tokenSent = false;
NotificationServices.RegisterForNotifications(
NotificationType.Alert |
NotificationType.Badge |
NotificationType.Sound, true);
}
void Update()
{
if (!tokenSent)
{
byte[] token = NotificationServices.deviceToken;
if (token != null)
{
// send token to a provider
string token = System.BitConverter.ToString(token).Replace('-', '%');
Debug.Log(token)
tokenSent = true;
}
}
}
}
The implementation is horrible, but we don't have callbacks from Unity side so we need to keep listening that variable value.
Check the documentation:
https://docs.unity3d.com/ScriptReference/iOS.NotificationServices.RegisterForNotifications.html
Also seems to need internet. I guess there is an Apple service going on there.
Yes, registration error is empty even when user deniy permissions.
What i did is to use UniRX and set an Observable fron a Coroutine with a time out so it dont keep forever asking for it.
If you accepted and you do not received the token might be the internet conection. And i guess you are teying this on a real device.
i've written an Azure function and connected the output to a notification-hub to send push notifications using APNS. It works fine as long as i send the notification to all registered devices, but i don't know how to use tags in order to address a specific user. If i try to use a tag, i get an error message saying "Exception while executing function: Functions.SendSinglePushNotification. Microsoft.Azure.WebJobs.Host: Error while handling parameter notification after function returned:. Microsoft.Azure.NotificationHubs: notification.Tag property should be null."
Here's my code so far:
#r "Microsoft.Azure.NotificationHubs"
#r "Newtonsoft.Json"
using System;
using Microsoft.Azure.NotificationHubs;
using Newtonsoft.Json;using
Microsoft.Azure.WebJobs.Host.Bindings.Runtime;
public static void Run(HttpRequestMessage req, TraceWriter log,Binder
binder, out AppleNotification notification)
{
string user = "Test";
string tagExpression = "Test";
string userTag = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "userid", true) == 0)
.Value;
string apnsNotificationPayload = "{\"aps\": {\"alert\": \"Test: (" + user + ")\" }}";
notification = new AppleNotification(apnsNotificationPayload);
}
I was trying to use notification = new
AppleNotification(apnsNotificationPayload,tagExpression);
but that does not work. How can i achieve that?
Thanks a lot and best regards
I had similar issue. Eventually, what worked for me was constructing Notification client manually. I am developing functions in Visual Studio, so my code is slightly different from yours.
[FunctionName("MyFunction")]
public static async Task Run([ServiceBusTrigger("queuename", AccessRights.Listen, Connection =
"<connection-settings-name>")] string myQueueItem, TraceWriter log)
{
log.Info($"C# Queue trigger function processed: {myQueueItem}");
var notificationHubSas = "<DefaultFullSharedAccessSignature from Azure portal>";
var notificationHubName = "myhub";
var nhClient = NotificationHubClient.CreateClientFromConnectionString(notificationHubSas, notificationHubName);
var tags = "";
await nhClient.SendTemplateNotificationAsync(<notification payload>, tags);
}
I want to store position coords (latitude, longitude) in a table in my MySQL DB querying a url in a way similar to this one: http://locationstore.com/postlocation.php?latitude=var1&longitude=var2 every ten seconds. PHP script works like a charm. Getting the coords in the device ain't no problem either. But making the request to the server is being a hard one. My code goes like this:
public class LocationHTTPSender extends Thread {
for (;;) {
try {
//fetch latest coordinates
coords = this.coords();
//reset url
this.url="http://locationstore.com/postlocation.php";
// create uri
uri = URI.create(this.url);
FireAndForgetDestination ffd = null;
ffd = (FireAndForgetDestination) DestinationFactory.getSenderDestination
("MyContext", uri);
if(ffd == null)
{
ffd = DestinationFactory.createFireAndForgetDestination
(new Context("MyContext"), uri);
}
ByteMessage myMsg = ffd.createByteMessage();
myMsg.setStringPayload("doesnt matter");
((HttpMessage) myMsg).setMethod(HttpMessage.POST);
((HttpMessage) myMsg).setQueryParam("latitude", coords[0]);
((HttpMessage) myMsg).setQueryParam("longitude", coords[1]);
((HttpMessage) myMsg).setQueryParam("user", "1");
int i = ffd.sendNoResponse(myMsg);
ffd.destroy();
System.out.println("Lets sleep for a while..");
Thread.sleep(10000);
System.out.println("woke up");
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("Exception message: " + e.toString());
e.printStackTrace();
}
}
I haven't run this code to test it, but I would be suspicious of this call:
ffd.destroy();
According to the API docs:
Closes the destination. This method cancels all outstanding messages,
discards all responses to those messages (if any), suspends delivery
of all incoming messages, and blocks any future receipt of messages
for this Destination. This method also destroys any persistable
outbound and inbound queues. If Destination uses the Push API, this
method will unregister associated push subscriptions. This method
should be called only during the removal of an application.
So, if you're seeing the first request succeed (at least sometimes), and subsequent requests fail, I would try removing that call to destroy().
See the BlackBerry docs example for this here
Ok so I finally got it running cheerfully. The problem was with the transport selection; even though this example delivered WAP2 (among others) as an available transport in my device, running the network diagnostics tool showed only BIS as available. It also gave me the connection parameters that I needed to append at the end of the URL (;deviceside=false;ConnectionUID=GPMDSEU01;ConnectionType=mds-public). The code ended up like this:
for (;;) {
try {
coords.refreshCoordinates();
this.defaultUrl();
this.setUrl(stringFuncs.replaceAll(this.getUrl(), "%latitude%", coords.getLatitude() + ""));
this.setUrl(stringFuncs.replaceAll(this.getUrl(), "%longitude%", coords.getLongitude() + ""));
cd = cf.getConnection(this.getUrl());
if (cd != null) {
try {
HttpConnection hc = (HttpConnection)cd.getConnection();
final int i = hc.getResponseCode();
hc.close();
} catch (Exception e) {
}
}
//dormir
Thread.sleep(15000);
} catch (Exception e) {
} finally {
//cerrar conexiones
//poner objetos a null
}
Thanks for your help #Nate, it's been very much appreciated.